mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfd862cb99 | ||
|
|
3571f35d0d | ||
|
|
a01e7b8619 |
@@ -85,7 +85,7 @@ _APP_COMPUTE_RUNTIMES_NETWORK=runtimes
|
||||
_APP_EXECUTOR_SECRET=your-secret-key
|
||||
_APP_EXECUTOR_HOST=http://exc1/v1
|
||||
_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1
|
||||
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.32
|
||||
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29
|
||||
_APP_MAINTENANCE_INTERVAL=86400
|
||||
_APP_MAINTENANCE_START_TIME=12:00
|
||||
_APP_MAINTENANCE_RETENTION_CACHE=2592000
|
||||
|
||||
+5
-5
@@ -415,8 +415,8 @@ In addition, you will also need to add some logic to the `reduce()` method of th
|
||||
|
||||
```php
|
||||
case $document->getCollection() === 'buckets':
|
||||
$files = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES)));
|
||||
$storage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE)));
|
||||
$files = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getSequence(), METRIC_BUCKET_ID_FILES)));
|
||||
$storage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getSequence(), METRIC_BUCKET_ID_FILES_STORAGE)));
|
||||
|
||||
if (!empty($files['value'])) {
|
||||
$metrics[] = [
|
||||
@@ -463,9 +463,9 @@ $queueForStatsUsage
|
||||
->addMetric(METRIC_BUILDS, 1)
|
||||
->addMetric(METRIC_BUILDS_STORAGE, $build->getAttribute('size', 0))
|
||||
->addMetric(METRIC_BUILDS_COMPUTE, (int)$build->getAttribute('duration', 0) * 1000)
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS), 1)
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE), $build->getAttribute('size', 0))
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE), (int)$build->getAttribute('duration', 0) * 1000)
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getSequence(), METRIC_FUNCTION_ID_BUILDS), 1)
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getSequence(), METRIC_FUNCTION_ID_BUILDS_STORAGE), $build->getAttribute('size', 0))
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getSequence(), METRIC_FUNCTION_ID_BUILDS_COMPUTE), (int)$build->getAttribute('duration', 0) * 1000)
|
||||
->setProject($project)
|
||||
->trigger();
|
||||
```
|
||||
|
||||
+6
-6
@@ -125,13 +125,13 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
return $database;
|
||||
@@ -145,13 +145,13 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$database
|
||||
@@ -167,7 +167,7 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
|
||||
return function (?Document $project = null) use ($pools, $cache, $database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
$database->setTenant($project->getSequence());
|
||||
return $database;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
|
||||
// set tenant
|
||||
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
$database->setTenant($project->getSequence());
|
||||
}
|
||||
|
||||
return $database;
|
||||
|
||||
@@ -1439,6 +1439,13 @@ return [
|
||||
'lengths' => [],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_roles'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['roles'],
|
||||
'lengths' => [128],
|
||||
'orders' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use Utopia\System\System;
|
||||
|
||||
$console = [
|
||||
'$id' => ID::custom('console'),
|
||||
'$internalId' => ID::custom('console'),
|
||||
'$sequence' => ID::custom('console'),
|
||||
'name' => 'Appwrite',
|
||||
'$collection' => ID::custom('projects'),
|
||||
'description' => 'Appwrite core engine',
|
||||
|
||||
@@ -393,16 +393,6 @@ return [
|
||||
'description' => 'Membership is already confirmed.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::MEMBERSHIP_DELETION_PROHIBITED => [
|
||||
'name' => Exception::MEMBERSHIP_DELETION_PROHIBITED,
|
||||
'description' => 'Membership deletion is prohibited.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::MEMBERSHIP_DOWNGRADE_PROHIBITED => [
|
||||
'name' => Exception::MEMBERSHIP_DOWNGRADE_PROHIBITED,
|
||||
'description' => 'Membership role downgrade is prohibited.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Avatars */
|
||||
Exception::AVATAR_SET_NOT_FOUND => [
|
||||
|
||||
@@ -217,7 +217,7 @@ return [
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '7.0.0',
|
||||
'version' => '6.2.3',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.0",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.0",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -8049,29 +8049,6 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/components\/schemas\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
@@ -8227,10 +8204,7 @@
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.0",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -7530,29 +7530,6 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/components\/schemas\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
@@ -7711,10 +7688,7 @@
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.3",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -4490,6 +4490,29 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/components\/schemas\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.3",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -8227,10 +8227,7 @@
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36590,6 +36587,12 @@
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
"x-example": "default",
|
||||
"nullable": true
|
||||
},
|
||||
"encrypt": {
|
||||
"type": "boolean",
|
||||
"description": "Defines whether this attribute is encrypted or not.",
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.3",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -7711,10 +7711,7 @@
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26558,6 +26555,12 @@
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
"x-example": "default",
|
||||
"nullable": true
|
||||
},
|
||||
"encrypt": {
|
||||
"type": "boolean",
|
||||
"description": "Defines whether this attribute is encrypted or not.",
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.0",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.0",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -8178,29 +8178,6 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/definitions\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
@@ -8346,16 +8323,13 @@
|
||||
"documents": {
|
||||
"type": "array",
|
||||
"description": "Array of document data as JSON objects. May contain partial documents.",
|
||||
"default": null,
|
||||
"default": [],
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.0",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -7649,29 +7649,6 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/definitions\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
@@ -7820,16 +7797,13 @@
|
||||
"documents": {
|
||||
"type": "array",
|
||||
"description": "Array of document data as JSON objects. May contain partial documents.",
|
||||
"default": null,
|
||||
"default": [],
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.3",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -4636,6 +4636,29 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/definitions\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "Create new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.3",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -8346,16 +8346,13 @@
|
||||
"documents": {
|
||||
"type": "array",
|
||||
"description": "Array of document data as JSON objects. May contain partial documents.",
|
||||
"default": null,
|
||||
"default": [],
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -36819,6 +36816,12 @@
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
"x-example": "default",
|
||||
"x-nullable": true
|
||||
},
|
||||
"encrypt": {
|
||||
"type": "boolean",
|
||||
"description": "Defines whether this attribute is encrypted or not.",
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"version": "1.7.4",
|
||||
"version": "1.7.3",
|
||||
"title": "Appwrite",
|
||||
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
|
||||
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
|
||||
@@ -7820,16 +7820,13 @@
|
||||
"documents": {
|
||||
"type": "array",
|
||||
"description": "Array of document data as JSON objects. May contain partial documents.",
|
||||
"default": null,
|
||||
"default": [],
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"documents"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -26854,6 +26851,12 @@
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
"x-example": "default",
|
||||
"x-nullable": true
|
||||
},
|
||||
"encrypt": {
|
||||
"type": "boolean",
|
||||
"description": "Defines whether this attribute is encrypted or not.",
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
||||
@@ -7,5 +7,4 @@ return [
|
||||
"png" => "image/png",
|
||||
"heic" => "image/heic",
|
||||
"webp" => "image/webp",
|
||||
"gif" => "image/gif",
|
||||
];
|
||||
|
||||
@@ -8,5 +8,4 @@ return [
|
||||
"webp" => "image/webp",
|
||||
"heic" => "image/heic",
|
||||
"avif" => "image/avif",
|
||||
"gif" => "image/gif",
|
||||
];
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\System\System;
|
||||
|
||||
Image::setResourceLimit('memory', intval(System::getEnv('_APP_IMAGES_RESOURCE_LIMIT_MEMORY', 1024*1024*64)));
|
||||
@@ -14,7 +14,7 @@ return [
|
||||
],
|
||||
'DART' => [
|
||||
'name' => 'dart',
|
||||
'versions' => ['3.8', '3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
|
||||
'versions' => ['3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
|
||||
],
|
||||
'GO' => [
|
||||
'name' => 'go',
|
||||
@@ -38,6 +38,6 @@ return [
|
||||
],
|
||||
'FLUTTER' => [
|
||||
'name' => 'flutter',
|
||||
'versions' => ['3.32', '3.24']
|
||||
'versions' => ['3.24']
|
||||
],
|
||||
];
|
||||
|
||||
@@ -190,7 +190,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'provider' => Auth::getSessionProviderByTokenType($verifiedToken->getAttribute('type')),
|
||||
'secret' => Auth::hash($sessionSecret), // One way hash encryption to protect DB leak
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
@@ -387,7 +387,7 @@ App::post('/v1/account')
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
$user->removeAttribute('$internalId');
|
||||
$user->removeAttribute('$sequence');
|
||||
$user = Authorization::skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
try {
|
||||
$target = Authorization::skip(fn () => $dbForProject->createDocument('targets', new Document([
|
||||
@@ -397,7 +397,7 @@ App::post('/v1/account')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => MESSAGE_TYPE_EMAIL,
|
||||
'identifier' => $email,
|
||||
])));
|
||||
@@ -907,7 +907,7 @@ App::post('/v1/account/sessions/email')
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'provider' => Auth::SESSION_PROVIDER_EMAIL,
|
||||
'providerUid' => $email,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
@@ -1056,7 +1056,7 @@ App::post('/v1/account/sessions/anonymous')
|
||||
'search' => $userId,
|
||||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
$user->removeAttribute('$internalId');
|
||||
$user->removeAttribute('$sequence');
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
|
||||
// Create session token
|
||||
@@ -1069,7 +1069,7 @@ App::post('/v1/account/sessions/anonymous')
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'provider' => Auth::SESSION_PROVIDER_ANONYMOUS,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
@@ -1440,7 +1440,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
|
||||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
Query::notEqual('userInternalId', $user->getSequence()),
|
||||
]);
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
$failureRedirect(Exception::USER_ALREADY_EXISTS);
|
||||
@@ -1554,7 +1554,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
$user->removeAttribute('$internalId');
|
||||
$user->removeAttribute('$sequence');
|
||||
$userDoc = Authorization::skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
$dbForProject->createDocument('targets', new Document([
|
||||
'$permissions' => [
|
||||
@@ -1563,7 +1563,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $userDoc->getId(),
|
||||
'userInternalId' => $userDoc->getInternalId(),
|
||||
'userInternalId' => $userDoc->getSequence(),
|
||||
'providerType' => MESSAGE_TYPE_EMAIL,
|
||||
'identifier' => $email,
|
||||
]));
|
||||
@@ -1582,7 +1582,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
}
|
||||
|
||||
$identity = $dbForProject->findOne('identities', [
|
||||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
Query::equal('userInternalId', [$user->getSequence()]),
|
||||
Query::equal('provider', [$provider]),
|
||||
Query::equal('providerUid', [$oauth2ID]),
|
||||
]);
|
||||
@@ -1592,7 +1592,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
|
||||
$identitiesWithMatchingEmail = $dbForProject->find('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
Query::notEqual('userInternalId', $user->getSequence()),
|
||||
]);
|
||||
if (!empty($identitiesWithMatchingEmail)) {
|
||||
$failureRedirect(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
@@ -1605,7 +1605,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
Permission::update(Role::user($userId)),
|
||||
Permission::delete(Role::user($userId)),
|
||||
],
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'userId' => $userId,
|
||||
'provider' => $provider,
|
||||
'providerUid' => $oauth2ID,
|
||||
@@ -1648,7 +1648,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
$token = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_OAUTH2,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
@@ -1683,7 +1683,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
$session = new Document(array_merge([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'provider' => $provider,
|
||||
'providerUid' => $oauth2ID,
|
||||
'providerAccessToken' => $accessToken,
|
||||
@@ -1736,7 +1736,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
|
||||
$target
|
||||
->setAttribute('sessionId', $session->getId())
|
||||
->setAttribute('sessionInternalId', $session->getInternalId());
|
||||
->setAttribute('sessionInternalId', $session->getSequence());
|
||||
|
||||
$dbForProject->updateDocument('targets', $target->getId(), $target);
|
||||
}
|
||||
@@ -1931,7 +1931,7 @@ App::post('/v1/account/tokens/magic-url')
|
||||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
|
||||
$user->removeAttribute('$internalId');
|
||||
$user->removeAttribute('$sequence');
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
}
|
||||
|
||||
@@ -1941,7 +1941,7 @@ App::post('/v1/account/tokens/magic-url')
|
||||
$token = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_MAGIC_URL,
|
||||
'secret' => Auth::hash($tokenSecret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
@@ -2168,7 +2168,7 @@ App::post('/v1/account/tokens/email')
|
||||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
|
||||
$user->removeAttribute('$internalId');
|
||||
$user->removeAttribute('$sequence');
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
}
|
||||
|
||||
@@ -2178,7 +2178,7 @@ App::post('/v1/account/tokens/email')
|
||||
$token = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_EMAIL,
|
||||
'secret' => Auth::hash($tokenSecret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
@@ -2460,7 +2460,7 @@ App::post('/v1/account/tokens/phone')
|
||||
'accessedAt' => DateTime::now(),
|
||||
]);
|
||||
|
||||
$user->removeAttribute('$internalId');
|
||||
$user->removeAttribute('$sequence');
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('users', $user));
|
||||
try {
|
||||
$target = Authorization::skip(fn () => $dbForProject->createDocument('targets', new Document([
|
||||
@@ -2470,7 +2470,7 @@ App::post('/v1/account/tokens/phone')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => MESSAGE_TYPE_SMS,
|
||||
'identifier' => $phone,
|
||||
])));
|
||||
@@ -2501,7 +2501,7 @@ App::post('/v1/account/tokens/phone')
|
||||
$token = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_PHONE,
|
||||
'secret' => Auth::hash($secret),
|
||||
'expire' => $expire,
|
||||
@@ -2703,7 +2703,7 @@ App::get('/v1/account/logs')
|
||||
|
||||
$audit = new EventAudit($dbForProject);
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getInternalId(), $queries);
|
||||
$logs = $audit->getLogsByUser($user->getSequence(), $queries);
|
||||
|
||||
$output = [];
|
||||
|
||||
@@ -2732,7 +2732,7 @@ App::get('/v1/account/logs')
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $audit->countLogsByUser($user->getInternalId(), $queries),
|
||||
'total' => $audit->countLogsByUser($user->getSequence(), $queries),
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
@@ -2900,7 +2900,7 @@ App::patch('/v1/account/email')
|
||||
// Makes sure this email is not already used in another identity
|
||||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
Query::notEqual('userInternalId', $user->getSequence()),
|
||||
]);
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
@@ -3183,7 +3183,7 @@ App::post('/v1/account/recovery')
|
||||
$recovery = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $profile->getId(),
|
||||
'userInternalId' => $profile->getInternalId(),
|
||||
'userInternalId' => $profile->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_RECOVERY,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
@@ -3438,7 +3438,7 @@ App::post('/v1/account/verification')
|
||||
$verification = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_VERIFICATION,
|
||||
'secret' => Auth::hash($verificationSecret), // One way hash encryption to protect DB leak
|
||||
'expire' => $expire,
|
||||
@@ -3685,7 +3685,7 @@ App::post('/v1/account/verification/phone')
|
||||
$verification = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_PHONE,
|
||||
'secret' => Auth::hash($secret),
|
||||
'expire' => $expire,
|
||||
@@ -3979,7 +3979,7 @@ App::post('/v1/account/mfa/authenticators/:type')
|
||||
$authenticator = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Type::TOTP,
|
||||
'verified' => false,
|
||||
'data' => [
|
||||
@@ -4292,7 +4292,7 @@ App::post('/v1/account/mfa/challenge')
|
||||
$code = Auth::codeGenerator();
|
||||
$challenge = new Document([
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => $factor,
|
||||
'token' => Auth::tokenGenerator(),
|
||||
'code' => $code,
|
||||
@@ -4621,12 +4621,12 @@ App::post('/v1/account/targets/push')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'providerId' => !empty($providerId) ? $providerId : null,
|
||||
'providerInternalId' => !empty($providerId) ? $provider->getInternalId() : null,
|
||||
'providerInternalId' => !empty($providerId) ? $provider->getSequence() : null,
|
||||
'providerType' => MESSAGE_TYPE_PUSH,
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'sessionId' => $session->getId(),
|
||||
'sessionInternalId' => $session->getInternalId(),
|
||||
'sessionInternalId' => $session->getSequence(),
|
||||
'identifier' => $identifier,
|
||||
'name' => "{$device['deviceBrand']} {$device['deviceModel']}"
|
||||
]));
|
||||
@@ -4745,7 +4745,7 @@ App::delete('/v1/account/targets/:targetId/push')
|
||||
throw new Exception(Exception::USER_TARGET_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($user->getInternalId() !== $target->getAttribute('userInternalId')) {
|
||||
if ($user->getSequence() !== $target->getAttribute('userInternalId')) {
|
||||
throw new Exception(Exception::USER_TARGET_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -4794,7 +4794,7 @@ App::get('/v1/account/identities')
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$queries[] = Query::equal('userInternalId', [$user->getInternalId()]);
|
||||
$queries[] = Query::equal('userInternalId', [$user->getSequence()]);
|
||||
|
||||
/**
|
||||
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
|
||||
|
||||
@@ -669,7 +669,7 @@ App::get('/v1/cards/cloud')
|
||||
}
|
||||
}
|
||||
|
||||
$isPlatinum = $user->getInternalId() % 100 === 0;
|
||||
$isPlatinum = $user->getSequence() % 100 === 0;
|
||||
} else {
|
||||
$name = $mock === 'normal-long' ? 'Sir First Walter O\'Brian Junior' : 'Walter O\'Brian';
|
||||
$createdAt = new \DateTime('now');
|
||||
@@ -859,7 +859,7 @@ App::get('/v1/cards/cloud-back')
|
||||
$isEmployee = \array_key_exists($email, $employees);
|
||||
|
||||
$isGolden = $isEmployee || $isHero || $isContributor;
|
||||
$isPlatinum = $user->getInternalId() % 100 === 0;
|
||||
$isPlatinum = $user->getSequence() % 100 === 0;
|
||||
} else {
|
||||
$userId = '63e0bcf3c3eb803ba530';
|
||||
|
||||
@@ -926,9 +926,9 @@ App::get('/v1/cards/cloud-og')
|
||||
}
|
||||
|
||||
if (!$mock) {
|
||||
$internalId = $user->getInternalId();
|
||||
$bgVariation = $internalId % 3 === 0 ? '1' : ($internalId % 3 === 1 ? '2' : '3');
|
||||
$cardVariation = $internalId % 3 === 0 ? '1' : ($internalId % 3 === 1 ? '2' : '3');
|
||||
$sequence = $user->getSequence();
|
||||
$bgVariation = $sequence % 3 === 0 ? '1' : ($sequence % 3 === 1 ? '2' : '3');
|
||||
$cardVariation = $sequence % 3 === 0 ? '1' : ($sequence % 3 === 1 ? '2' : '3');
|
||||
|
||||
$name = $user->getAttribute('name', 'Anonymous');
|
||||
$email = $user->getAttribute('email', '');
|
||||
@@ -958,7 +958,7 @@ App::get('/v1/cards/cloud-og')
|
||||
}
|
||||
}
|
||||
|
||||
$isPlatinum = $user->getInternalId() % 100 === 0;
|
||||
$isPlatinum = $user->getSequence() % 100 === 0;
|
||||
} else {
|
||||
$bgVariation = \str_ends_with($mock, '-bg2') ? '2' : (\str_ends_with($mock, '-bg3') ? '3' : '1');
|
||||
$cardVariation = \str_ends_with($mock, '-right') ? '2' : (\str_ends_with($mock, '-middle') ? '3' : '1');
|
||||
|
||||
+152
-135
@@ -107,7 +107,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -130,7 +130,7 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
|
||||
if ($type === Database::VAR_RELATIONSHIP) {
|
||||
$options['side'] = Database::RELATION_SIDE_PARENT;
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection'] ?? '');
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getSequence(), $options['relatedCollection'] ?? '');
|
||||
if ($relatedCollection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND, 'The related collection was not found.');
|
||||
}
|
||||
@@ -138,11 +138,11 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
|
||||
try {
|
||||
$attribute = new Document([
|
||||
'$id' => ID::custom($database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key),
|
||||
'$id' => ID::custom($database->getSequence() . '_' . $collection->getSequence() . '_' . $key),
|
||||
'key' => $key,
|
||||
'databaseInternalId' => $database->getInternalId(),
|
||||
'databaseInternalId' => $database->getSequence(),
|
||||
'databaseId' => $database->getId(),
|
||||
'collectionInternalId' => $collection->getInternalId(),
|
||||
'collectionInternalId' => $collection->getSequence(),
|
||||
'collectionId' => $collectionId,
|
||||
'type' => $type,
|
||||
'status' => 'processing', // processing, available, failed, deleting, stuck
|
||||
@@ -164,13 +164,13 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
} catch (LimitException) {
|
||||
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED);
|
||||
} catch (\Throwable $e) {
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
|
||||
if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) {
|
||||
$twoWayKey = $options['twoWayKey'];
|
||||
@@ -181,11 +181,11 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
try {
|
||||
try {
|
||||
$twoWayAttribute = new Document([
|
||||
'$id' => ID::custom($database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $twoWayKey),
|
||||
'$id' => ID::custom($database->getSequence() . '_' . $relatedCollection->getSequence() . '_' . $twoWayKey),
|
||||
'key' => $twoWayKey,
|
||||
'databaseInternalId' => $database->getInternalId(),
|
||||
'databaseInternalId' => $database->getSequence(),
|
||||
'databaseId' => $database->getId(),
|
||||
'collectionInternalId' => $relatedCollection->getInternalId(),
|
||||
'collectionInternalId' => $relatedCollection->getSequence(),
|
||||
'collectionId' => $relatedCollection->getId(),
|
||||
'type' => $type,
|
||||
'status' => 'processing', // processing, available, failed, deleting, stuck
|
||||
@@ -213,13 +213,13 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
$dbForProject->deleteDocument('attributes', $attribute->getId());
|
||||
throw $e;
|
||||
} finally {
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
}
|
||||
|
||||
// If operation succeeded, purge the cache for the related collection too
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence());
|
||||
}
|
||||
|
||||
$queueForDatabase
|
||||
@@ -262,12 +262,12 @@ function updateAttribute(
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
|
||||
$attribute = $dbForProject->getDocument('attributes', $database->getSequence() . '_' . $collection->getSequence() . '_' . $key);
|
||||
if ($attribute->isEmpty()) {
|
||||
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
|
||||
}
|
||||
@@ -292,7 +292,7 @@ function updateAttribute(
|
||||
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for array attributes');
|
||||
}
|
||||
|
||||
$collectionId = 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId();
|
||||
$collectionId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence();
|
||||
|
||||
$attribute
|
||||
->setAttribute('default', $default)
|
||||
@@ -378,8 +378,8 @@ function updateAttribute(
|
||||
}
|
||||
|
||||
if ($primaryDocumentOptions['twoWay']) {
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $primaryDocumentOptions['relatedCollection']);
|
||||
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $primaryDocumentOptions['twoWayKey']);
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getSequence(), $primaryDocumentOptions['relatedCollection']);
|
||||
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getSequence() . '_' . $relatedCollection->getSequence() . '_' . $primaryDocumentOptions['twoWayKey']);
|
||||
|
||||
if (!empty($newKey) && $newKey !== $key) {
|
||||
$options['twoWayKey'] = $newKey;
|
||||
@@ -389,8 +389,8 @@ function updateAttribute(
|
||||
$relatedAttribute->setAttribute('options', $relatedOptions);
|
||||
|
||||
|
||||
$dbForProject->updateDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $primaryDocumentOptions['twoWayKey'], $relatedAttribute);
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->updateDocument('attributes', $database->getSequence() . '_' . $relatedCollection->getSequence() . '_' . $primaryDocumentOptions['twoWayKey'], $relatedAttribute);
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $relatedCollection->getId());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
@@ -418,7 +418,7 @@ function updateAttribute(
|
||||
$originalUid = $attribute->getId();
|
||||
|
||||
$attribute
|
||||
->setAttribute('$id', ID::custom($database->getInternalId() . '_' . $collection->getInternalId() . '_' . $newKey))
|
||||
->setAttribute('$id', ID::custom($database->getSequence() . '_' . $collection->getSequence() . '_' . $newKey))
|
||||
->setAttribute('key', $newKey);
|
||||
|
||||
try {
|
||||
@@ -444,10 +444,10 @@ function updateAttribute(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$attribute = $dbForProject->updateDocument('attributes', $database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key, $attribute);
|
||||
$attribute = $dbForProject->updateDocument('attributes', $database->getSequence() . '_' . $collection->getSequence() . '_' . $key, $attribute);
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collection->getId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collection->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setContext('collection', $collection)
|
||||
@@ -536,7 +536,7 @@ App::post('/v1/databases')
|
||||
}
|
||||
|
||||
try {
|
||||
$dbForProject->createCollection('database_' . $database->getInternalId(), $attributes, $indexes);
|
||||
$dbForProject->createCollection('database_' . $database->getSequence(), $attributes, $indexes);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::DATABASE_ALREADY_EXISTS);
|
||||
} catch (IndexException) {
|
||||
@@ -839,7 +839,7 @@ App::delete('/v1/databases/:databaseId')
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('databases', $database->getId());
|
||||
$dbForProject->purgeCachedCollection('databases_' . $database->getInternalId());
|
||||
$dbForProject->purgeCachedCollection('databases_' . $database->getSequence());
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_DELETE_DATABASE)
|
||||
@@ -899,9 +899,9 @@ App::post('/v1/databases/:databaseId/collections')
|
||||
$permissions = Permission::aggregate($permissions) ?? [];
|
||||
|
||||
try {
|
||||
$collection = $dbForProject->createDocument('database_' . $database->getInternalId(), new Document([
|
||||
$collection = $dbForProject->createDocument('database_' . $database->getSequence(), new Document([
|
||||
'$id' => $collectionId,
|
||||
'databaseInternalId' => $database->getInternalId(),
|
||||
'databaseInternalId' => $database->getSequence(),
|
||||
'databaseId' => $databaseId,
|
||||
'$permissions' => $permissions,
|
||||
'documentSecurity' => $documentSecurity,
|
||||
@@ -919,7 +919,7 @@ App::post('/v1/databases/:databaseId/collections')
|
||||
|
||||
try {
|
||||
$dbForProject->createCollection(
|
||||
id: 'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
id: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
permissions: $permissions,
|
||||
documentSecurity: $documentSecurity
|
||||
);
|
||||
@@ -1000,7 +1000,7 @@ App::get('/v1/databases/:databaseId/collections')
|
||||
|
||||
$collectionId = $cursor->getValue();
|
||||
|
||||
$cursorDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$cursorDocument = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Collection '{$collectionId}' for the 'cursor' value not found.");
|
||||
@@ -1009,7 +1009,7 @@ App::get('/v1/databases/:databaseId/collections')
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
$collectionId = 'database_' . $database->getInternalId();
|
||||
$collectionId = 'database_' . $database->getSequence();
|
||||
|
||||
try {
|
||||
$collections = $dbForProject->find($collectionId, $queries);
|
||||
@@ -1057,7 +1057,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -1100,8 +1100,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId());
|
||||
$collectionDocument = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getSequence() . '_collection_' . $collectionDocument->getSequence());
|
||||
|
||||
if ($collectionDocument->isEmpty() || $collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -1215,7 +1215,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -1236,12 +1236,12 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
|
||||
->setAttribute('search', \implode(' ', [$collectionId, $name]));
|
||||
|
||||
$collection = $dbForProject->updateDocument(
|
||||
'database_' . $database->getInternalId(),
|
||||
'database_' . $database->getSequence(),
|
||||
$collectionId,
|
||||
$collection
|
||||
);
|
||||
|
||||
$dbForProject->updateCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $permissions, $documentSecurity);
|
||||
$dbForProject->updateCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $permissions, $documentSecurity);
|
||||
|
||||
$queueForEvents
|
||||
->setContext('database', $database)
|
||||
@@ -1287,17 +1287,17 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!$dbForProject->deleteDocument('database_' . $database->getInternalId(), $collectionId)) {
|
||||
if (!$dbForProject->deleteDocument('database_' . $database->getSequence(), $collectionId)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove collection from DB');
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_DELETE_COLLECTION)
|
||||
@@ -1347,7 +1347,17 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) {
|
||||
->inject('plan')
|
||||
->action(function (string $databaseId, string $collectionId, string $key, ?int $size, ?bool $required, ?string $default, bool $array, bool $encrypt, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, array $plan) {
|
||||
if ($encrypt && !empty($plan) && !($plan['databasesAllowEncrypt'] ?? false)) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Encrypted string attributes are not available on your plan. Please upgrade to create encrypted string attributes.');
|
||||
}
|
||||
if ($encrypt && $size < APP_DATABASE_ENCRYPT_SIZE_MIN) {
|
||||
throw new Exception(
|
||||
Exception::GENERAL_BAD_REQUEST,
|
||||
"Size too small. Encrypted strings require a minimum size of " . APP_DATABASE_ENCRYPT_SIZE_MIN . " characters."
|
||||
);
|
||||
}
|
||||
// Ensure attribute default is within required size
|
||||
$validator = new Text($size, 0);
|
||||
if (!is_null($default) && !$validator->isValid($default)) {
|
||||
@@ -1368,7 +1378,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string
|
||||
'array' => $array,
|
||||
'filters' => $filters,
|
||||
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
|
||||
|
||||
$attribute->setAttribute('encrypt', $encrypt);
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_ACCEPTED)
|
||||
->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING);
|
||||
@@ -1878,15 +1888,15 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relati
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$relatedCollectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId);
|
||||
$relatedCollection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollectionDocument->getInternalId());
|
||||
$relatedCollectionDocument = $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId);
|
||||
$relatedCollection = $dbForProject->getCollection('database_' . $database->getSequence() . '_collection_' . $relatedCollectionDocument->getSequence());
|
||||
|
||||
if ($relatedCollection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -1987,7 +1997,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -2000,8 +2010,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
|
||||
|
||||
\array_push(
|
||||
$queries,
|
||||
Query::equal('databaseInternalId', [$database->getInternalId()]),
|
||||
Query::equal('collectionInternalId', [$collection->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$database->getSequence()]),
|
||||
Query::equal('collectionInternalId', [$collection->getSequence()]),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -2023,8 +2033,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
|
||||
|
||||
try {
|
||||
$cursorDocument = $dbForProject->findOne('attributes', [
|
||||
Query::equal('databaseInternalId', [$database->getInternalId()]),
|
||||
Query::equal('collectionInternalId', [$collection->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$database->getSequence()]),
|
||||
Query::equal('collectionInternalId', [$collection->getSequence()]),
|
||||
Query::equal('key', [$attributeId]),
|
||||
]);
|
||||
} catch (QueryException $e) {
|
||||
@@ -2047,6 +2057,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID);
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute->getAttribute('type') === Database::VAR_STRING) {
|
||||
$filters = $attribute->getAttribute('filters', []);
|
||||
$attribute->setAttribute('encrypt', in_array('encrypt', $filters));
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'attributes' => $attributes,
|
||||
'total' => $total,
|
||||
@@ -2095,13 +2112,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
|
||||
$attribute = $dbForProject->getDocument('attributes', $database->getSequence() . '_' . $collection->getSequence() . '_' . $key);
|
||||
|
||||
if ($attribute->isEmpty()) {
|
||||
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
|
||||
@@ -2111,7 +2128,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
|
||||
$type = $attribute->getAttribute('type');
|
||||
$format = $attribute->getAttribute('format');
|
||||
$options = $attribute->getAttribute('options', []);
|
||||
|
||||
$filters = $attribute->getAttribute('filters', []);
|
||||
foreach ($options as $key => $option) {
|
||||
$attribute->setAttribute($key, $option);
|
||||
}
|
||||
@@ -2131,7 +2148,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
|
||||
},
|
||||
default => Response::MODEL_ATTRIBUTE,
|
||||
};
|
||||
|
||||
$attribute->setAttribute('encrypt', in_array('encrypt', $filters));
|
||||
$response->dynamic($attribute, $model);
|
||||
});
|
||||
|
||||
@@ -2708,13 +2725,13 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
|
||||
$attribute = $dbForProject->getDocument('attributes', $database->getSequence() . '_' . $collection->getSequence() . '_' . $key);
|
||||
|
||||
if ($attribute->isEmpty()) {
|
||||
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
|
||||
@@ -2737,19 +2754,19 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
|
||||
$attribute = $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
|
||||
if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) {
|
||||
$options = $attribute->getAttribute('options');
|
||||
if ($options['twoWay']) {
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']);
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getSequence(), $options['relatedCollection']);
|
||||
|
||||
if ($relatedCollection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']);
|
||||
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getSequence() . '_' . $relatedCollection->getSequence() . '_' . $options['twoWayKey']);
|
||||
|
||||
if ($relatedAttribute->isEmpty()) {
|
||||
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
|
||||
@@ -2759,8 +2776,8 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
|
||||
$dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $options['relatedCollection']);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $options['relatedCollection']);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2842,7 +2859,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -2851,8 +2868,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
$limit = $dbForProject->getLimitForIndexes();
|
||||
|
||||
$count = $dbForProject->count('indexes', [
|
||||
Query::equal('collectionInternalId', [$collection->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$database->getInternalId()])
|
||||
Query::equal('collectionInternalId', [$collection->getSequence()]),
|
||||
Query::equal('databaseInternalId', [$database->getSequence()])
|
||||
], max: $limit);
|
||||
|
||||
|
||||
@@ -2922,12 +2939,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
}
|
||||
|
||||
$index = new Document([
|
||||
'$id' => ID::custom($database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key),
|
||||
'$id' => ID::custom($database->getSequence() . '_' . $collection->getSequence() . '_' . $key),
|
||||
'key' => $key,
|
||||
'status' => 'processing', // processing, available, failed, deleting, stuck
|
||||
'databaseInternalId' => $database->getInternalId(),
|
||||
'databaseInternalId' => $database->getSequence(),
|
||||
'databaseId' => $databaseId,
|
||||
'collectionInternalId' => $collection->getInternalId(),
|
||||
'collectionInternalId' => $collection->getSequence(),
|
||||
'collectionId' => $collectionId,
|
||||
'type' => $type,
|
||||
'attributes' => $attributes,
|
||||
@@ -2951,7 +2968,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
throw new Exception(Exception::INDEX_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_CREATE_INDEX)
|
||||
@@ -3003,7 +3020,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -3034,8 +3051,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
|
||||
$indexId = $cursor->getValue();
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->find('indexes', [
|
||||
Query::equal('collectionInternalId', [$collection->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$database->getInternalId()]),
|
||||
Query::equal('collectionInternalId', [$collection->getSequence()]),
|
||||
Query::equal('databaseInternalId', [$database->getSequence()]),
|
||||
Query::equal('key', [$indexId]),
|
||||
Query::limit(1)
|
||||
]));
|
||||
@@ -3094,7 +3111,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -3147,13 +3164,13 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$index = $dbForProject->getDocument('indexes', $database->getInternalId() . '_' . $collection->getInternalId() . '_' . $key);
|
||||
$index = $dbForProject->getDocument('indexes', $database->getSequence() . '_' . $collection->getSequence() . '_' . $key);
|
||||
|
||||
if ($index->isEmpty()) {
|
||||
throw new Exception(Exception::INDEX_NOT_FOUND);
|
||||
@@ -3164,7 +3181,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
|
||||
$index = $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collectionId);
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_DELETE_INDEX)
|
||||
@@ -3300,7 +3317,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -3409,7 +3426,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($relations as &$relation) {
|
||||
@@ -3423,7 +3440,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
}
|
||||
if ($relation instanceof Document) {
|
||||
$current = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(), $relation->getId())
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(), $relation->getId())
|
||||
);
|
||||
|
||||
if ($current->isEmpty()) {
|
||||
@@ -3478,7 +3495,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
try {
|
||||
$dbForProject->createDocuments(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
$documents
|
||||
);
|
||||
} catch (DuplicateException) {
|
||||
@@ -3520,7 +3537,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($related as $relation) {
|
||||
@@ -3537,7 +3554,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations)); // per collection
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations)); // per collection
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
||||
@@ -3595,7 +3612,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -3623,7 +3640,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$documentId = $cursor->getValue();
|
||||
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Document '{$documentId}' for the 'cursor' value not found.");
|
||||
@@ -3632,8 +3649,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
try {
|
||||
$documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries);
|
||||
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT);
|
||||
$documents = $dbForProject->find('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries);
|
||||
$total = $dbForProject->count('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $queries, APP_LIMIT_COUNT);
|
||||
} catch (OrderException $e) {
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
} catch (QueryException $e) {
|
||||
@@ -3677,7 +3694,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
// todo: Use local cache for this getDocument
|
||||
$relatedCollection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId));
|
||||
$relatedCollection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId));
|
||||
|
||||
foreach ($relations as $index => $doc) {
|
||||
if ($doc instanceof Document) {
|
||||
@@ -3703,7 +3720,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS), \max(1, $operations));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS), \max(1, $operations));
|
||||
|
||||
$select = \array_reduce($queries, function ($result, $query) {
|
||||
return $result || ($query->getMethod() === Query::TYPE_SELECT);
|
||||
@@ -3774,7 +3791,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -3786,7 +3803,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
}
|
||||
|
||||
try {
|
||||
$document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId, $queries);
|
||||
$document = $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId, $queries);
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
@@ -3830,7 +3847,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($related as $relation) {
|
||||
@@ -3845,7 +3862,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS), \max(1, $operations));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS), \max(1, $operations));
|
||||
|
||||
$response->dynamic($document, Response::MODEL_DOCUMENT);
|
||||
});
|
||||
@@ -3884,12 +3901,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$document = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId);
|
||||
$document = $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId);
|
||||
|
||||
if ($document->isEmpty()) {
|
||||
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
|
||||
@@ -4013,13 +4030,13 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Read permission should not be required for update
|
||||
$document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId));
|
||||
$document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
|
||||
if ($document->isEmpty()) {
|
||||
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
|
||||
}
|
||||
@@ -4088,7 +4105,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($relations as &$relation) {
|
||||
@@ -4103,7 +4120,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
}
|
||||
if ($relation instanceof Document) {
|
||||
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
|
||||
$relation->getId()
|
||||
));
|
||||
$relation->removeAttribute('$collectionId');
|
||||
@@ -4111,7 +4128,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
// Attribute $collection is required for Utopia.
|
||||
$relation->setAttribute(
|
||||
'$collection',
|
||||
'database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId()
|
||||
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence()
|
||||
);
|
||||
|
||||
if ($oldDocument->isEmpty()) {
|
||||
@@ -4135,11 +4152,11 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
|
||||
try {
|
||||
$document = $dbForProject->updateDocument(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
$document->getId(),
|
||||
$newDocument
|
||||
);
|
||||
@@ -4175,7 +4192,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($related as $relation) {
|
||||
@@ -4257,7 +4274,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -4322,7 +4339,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($relations as &$relation) {
|
||||
@@ -4337,7 +4354,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
}
|
||||
if ($relation instanceof Document) {
|
||||
$oldDocument = Authorization::skip(fn () => $dbForProject->getDocument(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence(),
|
||||
$relation->getId()
|
||||
));
|
||||
$relation->removeAttribute('$collectionId');
|
||||
@@ -4345,7 +4362,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
// Attribute $collection is required for Utopia.
|
||||
$relation->setAttribute(
|
||||
'$collection',
|
||||
'database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId()
|
||||
'database_' . $database->getSequence() . '_collection_' . $relatedCollection->getSequence()
|
||||
);
|
||||
|
||||
if ($oldDocument->isEmpty()) {
|
||||
@@ -4369,12 +4386,12 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
|
||||
$upserted = [];
|
||||
try {
|
||||
$modified = $dbForProject->createOrUpdateDocuments(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
[$newDocument],
|
||||
onNext: function (Document $document) use (&$upserted) {
|
||||
$upserted[] = $document;
|
||||
@@ -4413,7 +4430,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($related as $relation) {
|
||||
@@ -4492,7 +4509,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -4523,7 +4540,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
try {
|
||||
$modified = $dbForProject->updateDocuments(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
new Document($data),
|
||||
$queries,
|
||||
onNext: function (Document $document) use ($plan, &$documents) {
|
||||
@@ -4547,7 +4564,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $modified,
|
||||
@@ -4581,7 +4598,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
))
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID.')
|
||||
->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of document data as JSON objects. May contain partial documents.', false, ['plan'])
|
||||
->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of document data as JSON objects. May contain partial documents.', true, ['plan'])
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForStatsUsage')
|
||||
@@ -4592,7 +4609,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -4614,7 +4631,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
try {
|
||||
$modified = $dbForProject->createOrUpdateDocuments(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
$documents,
|
||||
onNext: function (Document $document) use ($plan, &$upserted) {
|
||||
if (\count($upserted) < ($plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH)) {
|
||||
@@ -4639,7 +4656,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $modified,
|
||||
@@ -4690,20 +4707,20 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Read permission should not be required for delete
|
||||
$document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $documentId));
|
||||
$document = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $documentId));
|
||||
if ($document->isEmpty()) {
|
||||
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$dbForProject->deleteDocument(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
$documentId
|
||||
);
|
||||
} catch (ConflictException) {
|
||||
@@ -4738,7 +4755,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
||||
|
||||
$relatedCollectionId = $relationship->getAttribute('relatedCollection');
|
||||
$relatedCollection = Authorization::skip(
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedCollectionId)
|
||||
fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $relatedCollectionId)
|
||||
);
|
||||
|
||||
foreach ($related as $relation) {
|
||||
@@ -4753,7 +4770,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
|
||||
$relationships = \array_map(
|
||||
fn ($document) => $document->getAttribute('key'),
|
||||
@@ -4812,7 +4829,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
@@ -4836,7 +4853,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
try {
|
||||
$modified = $dbForProject->deleteDocuments(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
$queries,
|
||||
onNext: function (Document $document) use ($plan, &$documents) {
|
||||
if (\count($documents) < ($plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH)) {
|
||||
@@ -4857,7 +4874,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $modified,
|
||||
@@ -4993,11 +5010,11 @@ App::get('/v1/databases/:databaseId/usage')
|
||||
$stats = $usage = [];
|
||||
$days = $periods[$range];
|
||||
$metrics = [
|
||||
str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_COLLECTIONS),
|
||||
str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_DOCUMENTS),
|
||||
str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_STORAGE),
|
||||
str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS),
|
||||
str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES)
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_COLLECTIONS),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_DOCUMENTS),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_STORAGE),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES)
|
||||
];
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
@@ -5086,8 +5103,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $databaseId, string $range, string $collectionId, Response $response, Database $dbForProject) {
|
||||
$database = $dbForProject->getDocument('databases', $databaseId);
|
||||
$collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId());
|
||||
$collectionDocument = $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getSequence() . '_collection_' . $collectionDocument->getSequence());
|
||||
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
@@ -5097,7 +5114,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/usage')
|
||||
$stats = $usage = [];
|
||||
$days = $periods[$range];
|
||||
$metrics = [
|
||||
str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getInternalId(), $collectionDocument->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS),
|
||||
str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collectionDocument->getSequence()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS),
|
||||
];
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
|
||||
@@ -845,15 +845,18 @@ App::get('/v1/health/storage')
|
||||
$checkStart = \microtime(true);
|
||||
|
||||
foreach ($devices as $device) {
|
||||
if (!$device->write($device->getPath('health.txt'), 'test', 'text/plain')) {
|
||||
$uniqueFileName = \uniqid('health', true);
|
||||
$filePath = $device->getPath($uniqueFileName);
|
||||
|
||||
if (!$device->write($filePath, 'test', 'text/plain')) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot());
|
||||
}
|
||||
|
||||
if ($device->read($device->getPath('health.txt')) !== 'test') {
|
||||
if ($device->read($filePath) !== 'test') {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot());
|
||||
}
|
||||
|
||||
if (!$device->delete($device->getPath('health.txt'))) {
|
||||
if (!$device->delete($filePath)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2511,11 +2511,11 @@ App::post('/v1/messaging/topics/:topicId/subscribers')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'topicId' => $topicId,
|
||||
'topicInternalId' => $topic->getInternalId(),
|
||||
'topicInternalId' => $topic->getSequence(),
|
||||
'targetId' => $targetId,
|
||||
'targetInternalId' => $target->getInternalId(),
|
||||
'targetInternalId' => $target->getSequence(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => $target->getAttribute('providerType'),
|
||||
'search' => implode(' ', [
|
||||
$subscriberId,
|
||||
@@ -2597,7 +2597,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
throw new Exception(Exception::TOPIC_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries[] = Query::equal('topicInternalId', [$topic->getInternalId()]);
|
||||
$queries[] = Query::equal('topicInternalId', [$topic->getSequence()]);
|
||||
|
||||
/**
|
||||
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
|
||||
@@ -2947,7 +2947,7 @@ App::post('/v1/messaging/messages/email')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
@@ -2989,7 +2989,7 @@ App::post('/v1/messaging/messages/email')
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
'resourceInternalId' => $message->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $scheduledAt,
|
||||
@@ -3112,7 +3112,7 @@ App::post('/v1/messaging/messages/sms')
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
'resourceInternalId' => $message->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $scheduledAt,
|
||||
@@ -3232,7 +3232,7 @@ App::post('/v1/messaging/messages/push')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
@@ -3330,7 +3330,7 @@ App::post('/v1/messaging/messages/push')
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
'resourceInternalId' => $message->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $scheduledAt,
|
||||
@@ -3731,7 +3731,7 @@ App::patch('/v1/messaging/messages/email/:messageId')
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
'resourceInternalId' => $message->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $scheduledAt,
|
||||
@@ -3796,7 +3796,7 @@ App::patch('/v1/messaging/messages/email/:messageId')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
@@ -3933,7 +3933,7 @@ App::patch('/v1/messaging/messages/sms/:messageId')
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
'resourceInternalId' => $message->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $scheduledAt,
|
||||
@@ -4107,7 +4107,7 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
'resourceInternalId' => $message->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $project->getId(),
|
||||
'schedule' => $scheduledAt,
|
||||
@@ -4210,7 +4210,7 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ App::post('/v1/migrations/csv')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ App::get('/v1/project/usage')
|
||||
$executionsBreakdown = array_map(function ($function) use ($dbForProject) {
|
||||
$id = $function->getId();
|
||||
$name = $function->getAttribute('name');
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS);
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS);
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
@@ -166,7 +166,7 @@ App::get('/v1/project/usage')
|
||||
$executionsMbSecondsBreakdown = array_map(function ($function) use ($dbForProject) {
|
||||
$id = $function->getId();
|
||||
$name = $function->getAttribute('name');
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
@@ -182,7 +182,7 @@ App::get('/v1/project/usage')
|
||||
$buildsMbSecondsBreakdown = array_map(function ($function) use ($dbForProject) {
|
||||
$id = $function->getId();
|
||||
$name = $function->getAttribute('name');
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
@@ -198,7 +198,7 @@ App::get('/v1/project/usage')
|
||||
$bucketsBreakdown = array_map(function ($bucket) use ($dbForProject) {
|
||||
$id = $bucket->getId();
|
||||
$name = $bucket->getAttribute('name');
|
||||
$metric = str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE);
|
||||
$metric = str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_STORAGE);
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
@@ -214,7 +214,7 @@ App::get('/v1/project/usage')
|
||||
$databasesStorageBreakdown = array_map(function ($database) use ($dbForProject) {
|
||||
$id = $database->getId();
|
||||
$name = $database->getAttribute('name');
|
||||
$metric = str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_STORAGE);
|
||||
$metric = str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_STORAGE);
|
||||
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
@@ -231,13 +231,13 @@ App::get('/v1/project/usage')
|
||||
$functionsStorageBreakdown = array_map(function ($function) use ($dbForProject) {
|
||||
$id = $function->getId();
|
||||
$name = $function->getAttribute('name');
|
||||
$deploymentMetric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE);
|
||||
$deploymentMetric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE);
|
||||
$deploymentValue = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$deploymentMetric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$buildMetric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE);
|
||||
$buildMetric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE);
|
||||
$buildValue = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$buildMetric]),
|
||||
Query::equal('period', ['inf'])
|
||||
@@ -255,7 +255,7 @@ App::get('/v1/project/usage')
|
||||
$executionsMbSecondsBreakdown = array_map(function ($function) use ($dbForProject) {
|
||||
$id = $function->getId();
|
||||
$name = $function->getAttribute('name');
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
@@ -271,7 +271,7 @@ App::get('/v1/project/usage')
|
||||
$buildsMbSecondsBreakdown = array_map(function ($function) use ($dbForProject) {
|
||||
$id = $function->getId();
|
||||
$name = $function->getAttribute('name');
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
|
||||
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
|
||||
$value = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
|
||||
@@ -182,7 +182,7 @@ App::post('/v1/projects')
|
||||
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
|
||||
],
|
||||
'name' => $name,
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'teamInternalId' => $team->getSequence(),
|
||||
'teamId' => $team->getId(),
|
||||
'region' => $region,
|
||||
'description' => $description,
|
||||
@@ -230,13 +230,13 @@ App::post('/v1/projects')
|
||||
if ($sharedTables) {
|
||||
$dbForProject
|
||||
->setSharedTables(true)
|
||||
->setTenant($sharedTablesV1 ? $project->getInternalId() : null)
|
||||
->setTenant($sharedTablesV1 ? $project->getSequence() : null)
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$dbForProject
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$create = true;
|
||||
@@ -504,12 +504,12 @@ App::patch('/v1/projects/:projectId/team')
|
||||
|
||||
$project
|
||||
->setAttribute('teamId', $teamId)
|
||||
->setAttribute('teamInternalId', $team->getInternalId())
|
||||
->setAttribute('teamInternalId', $team->getSequence())
|
||||
->setAttribute('$permissions', $permissions);
|
||||
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project);
|
||||
|
||||
$installations = $dbForPlatform->find('installations', [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
foreach ($installations as $installation) {
|
||||
$installation->getAttribute('$permissions', $permissions);
|
||||
@@ -517,7 +517,7 @@ App::patch('/v1/projects/:projectId/team')
|
||||
}
|
||||
|
||||
$repositories = $dbForPlatform->find('repositories', [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
foreach ($repositories as $repository) {
|
||||
$repository->getAttribute('$permissions', $permissions);
|
||||
@@ -525,7 +525,7 @@ App::patch('/v1/projects/:projectId/team')
|
||||
}
|
||||
|
||||
$vcsComments = $dbForPlatform->find('vcsComments', [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
foreach ($vcsComments as $vcsComment) {
|
||||
$vcsComment->getAttribute('$permissions', $permissions);
|
||||
@@ -1229,7 +1229,7 @@ App::post('/v1/projects/:projectId/webhooks')
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'projectId' => $project->getId(),
|
||||
'name' => $name,
|
||||
'events' => $events,
|
||||
@@ -1279,7 +1279,7 @@ App::get('/v1/projects/:projectId/webhooks')
|
||||
}
|
||||
|
||||
$webhooks = $dbForPlatform->find('webhooks', [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
@@ -1320,7 +1320,7 @@ App::get('/v1/projects/:projectId/webhooks/:webhookId')
|
||||
|
||||
$webhook = $dbForPlatform->findOne('webhooks', [
|
||||
Query::equal('$id', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($webhook->isEmpty()) {
|
||||
@@ -1370,7 +1370,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
|
||||
|
||||
$webhook = $dbForPlatform->findOne('webhooks', [
|
||||
Query::equal('$id', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($webhook->isEmpty()) {
|
||||
@@ -1427,7 +1427,7 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature')
|
||||
|
||||
$webhook = $dbForPlatform->findOne('webhooks', [
|
||||
Query::equal('$id', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($webhook->isEmpty()) {
|
||||
@@ -1474,7 +1474,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
|
||||
|
||||
$webhook = $dbForPlatform->findOne('webhooks', [
|
||||
Query::equal('$id', [$webhookId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($webhook->isEmpty()) {
|
||||
@@ -1528,7 +1528,7 @@ App::post('/v1/projects/:projectId/keys')
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'projectId' => $project->getId(),
|
||||
'name' => $name,
|
||||
'scopes' => $scopes,
|
||||
@@ -1576,7 +1576,7 @@ App::get('/v1/projects/:projectId/keys')
|
||||
}
|
||||
|
||||
$keys = $dbForPlatform->find('keys', [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
@@ -1617,7 +1617,7 @@ App::get('/v1/projects/:projectId/keys/:keyId')
|
||||
|
||||
$key = $dbForPlatform->findOne('keys', [
|
||||
Query::equal('$id', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($key->isEmpty()) {
|
||||
@@ -1661,7 +1661,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
||||
|
||||
$key = $dbForPlatform->findOne('keys', [
|
||||
Query::equal('$id', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($key->isEmpty()) {
|
||||
@@ -1712,7 +1712,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
||||
|
||||
$key = $dbForPlatform->findOne('keys', [
|
||||
Query::equal('$id', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($key->isEmpty()) {
|
||||
@@ -1811,7 +1811,7 @@ App::post('/v1/projects/:projectId/platforms')
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'projectId' => $project->getId(),
|
||||
'type' => $type,
|
||||
'name' => $name,
|
||||
@@ -1858,7 +1858,7 @@ App::get('/v1/projects/:projectId/platforms')
|
||||
}
|
||||
|
||||
$platforms = $dbForPlatform->find('platforms', [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
@@ -1899,7 +1899,7 @@ App::get('/v1/projects/:projectId/platforms/:platformId')
|
||||
|
||||
$platform = $dbForPlatform->findOne('platforms', [
|
||||
Query::equal('$id', [$platformId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($platform->isEmpty()) {
|
||||
@@ -1943,7 +1943,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
||||
|
||||
$platform = $dbForPlatform->findOne('platforms', [
|
||||
Query::equal('$id', [$platformId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($platform->isEmpty()) {
|
||||
@@ -1997,7 +1997,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
|
||||
|
||||
$platform = $dbForPlatform->findOne('platforms', [
|
||||
Query::equal('$id', [$platformId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($platform->isEmpty()) {
|
||||
|
||||
@@ -58,7 +58,7 @@ App::get('/v1/proxy/rules')
|
||||
$queries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$queries[] = Query::equal('projectInternalId', [$project->getInternalId()]);
|
||||
$queries[] = Query::equal('projectInternalId', [$project->getSequence()]);
|
||||
|
||||
/**
|
||||
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
|
||||
@@ -124,7 +124,7 @@ App::get('/v1/proxy/rules/:ruleId')
|
||||
->action(function (string $ruleId, Response $response, Document $project, Database $dbForPlatform) {
|
||||
$rule = $dbForPlatform->getDocument('rules', $ruleId);
|
||||
|
||||
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getInternalId()) {
|
||||
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getSequence()) {
|
||||
throw new Exception(Exception::RULE_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ App::delete('/v1/proxy/rules/:ruleId')
|
||||
->action(function (string $ruleId, Response $response, Document $project, Database $dbForPlatform, Delete $queueForDeletes, Event $queueForEvents) {
|
||||
$rule = $dbForPlatform->getDocument('rules', $ruleId);
|
||||
|
||||
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getInternalId()) {
|
||||
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getSequence()) {
|
||||
throw new Exception(Exception::RULE_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
||||
->action(function (string $ruleId, Response $response, Certificate $queueForCertificates, Event $queueForEvents, Document $project, Database $dbForPlatform, Log $log) {
|
||||
$rule = $dbForPlatform->getDocument('rules', $ruleId);
|
||||
|
||||
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getInternalId()) {
|
||||
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getSequence()) {
|
||||
throw new Exception(Exception::RULE_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ App::post('/v1/storage/buckets')
|
||||
|
||||
$bucket = $dbForProject->getDocument('buckets', $bucketId);
|
||||
|
||||
$dbForProject->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes, permissions: $permissions ?? [], documentSecurity: $fileSecurity);
|
||||
$dbForProject->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes, permissions: $permissions ?? [], documentSecurity: $fileSecurity);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -326,7 +326,7 @@ App::put('/v1/storage/buckets/:bucketId')
|
||||
->setAttribute('compression', $compression)
|
||||
->setAttribute('antivirus', $antivirus));
|
||||
|
||||
$dbForProject->updateCollection('bucket_' . $bucket->getInternalId(), $permissions, $fileSecurity);
|
||||
$dbForProject->updateCollection('bucket_' . $bucket->getSequence(), $permissions, $fileSecurity);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('bucketId', $bucket->getId());
|
||||
@@ -558,7 +558,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
$path = $deviceForFiles->getPath($fileId . '.' . \pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
$path = str_ireplace($deviceForFiles->getRoot(), $deviceForFiles->getRoot() . DIRECTORY_SEPARATOR . $bucket->getId(), $path); // Add bucket id to path after root
|
||||
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
|
||||
$metadata = ['content_type' => $deviceForLocal->getFileMimeType($fileTmpName)];
|
||||
if (!$file->isEmpty()) {
|
||||
@@ -652,7 +652,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
'$id' => $fileId,
|
||||
'$permissions' => $permissions,
|
||||
'bucketId' => $bucket->getId(),
|
||||
'bucketInternalId' => $bucket->getInternalId(),
|
||||
'bucketInternalId' => $bucket->getSequence(),
|
||||
'name' => $fileName,
|
||||
'path' => $path,
|
||||
'signature' => $fileHash,
|
||||
@@ -671,7 +671,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
'metadata' => $metadata,
|
||||
]);
|
||||
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc);
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
} else {
|
||||
$file = $file
|
||||
->setAttribute('$permissions', $permissions)
|
||||
@@ -696,7 +696,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
if (!$validator->isValid($bucket->getCreate())) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file));
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
}
|
||||
} else {
|
||||
if ($file->isEmpty()) {
|
||||
@@ -704,7 +704,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
'$id' => ID::custom($fileId),
|
||||
'$permissions' => $permissions,
|
||||
'bucketId' => $bucket->getId(),
|
||||
'bucketInternalId' => $bucket->getInternalId(),
|
||||
'bucketInternalId' => $bucket->getSequence(),
|
||||
'name' => $fileName,
|
||||
'path' => $path,
|
||||
'signature' => '',
|
||||
@@ -720,7 +720,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
]);
|
||||
|
||||
try {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc);
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
@@ -741,7 +741,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
}
|
||||
|
||||
try {
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file));
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
@@ -826,9 +826,9 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
||||
$fileId = $cursor->getValue();
|
||||
|
||||
if ($fileSecurity && !$valid) {
|
||||
$cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
@@ -842,11 +842,11 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
||||
|
||||
try {
|
||||
if ($fileSecurity && !$valid) {
|
||||
$files = $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries);
|
||||
$total = $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT);
|
||||
$files = $dbForProject->find('bucket_' . $bucket->getSequence(), $queries);
|
||||
$total = $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT);
|
||||
} else {
|
||||
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries));
|
||||
$total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT));
|
||||
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getSequence(), $queries));
|
||||
$total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT));
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -902,9 +902,9 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
@@ -973,7 +973,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
@@ -982,12 +982,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid && !$isToken) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -1150,7 +1150,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
@@ -1159,12 +1159,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -1309,7 +1309,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
@@ -1318,12 +1318,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@@ -1478,7 +1478,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
@@ -1643,7 +1643,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
}
|
||||
|
||||
// Read permission should not be required for update
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
@@ -1689,9 +1689,9 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
|
||||
try {
|
||||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
|
||||
$file = $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file);
|
||||
} else {
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file));
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -1757,7 +1757,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
}
|
||||
|
||||
// Read permission should not be required for delete
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
@@ -1787,9 +1787,9 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
|
||||
try {
|
||||
if ($fileSecurity && !$valid) {
|
||||
$deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -1937,14 +1937,14 @@ App::get('/v1/storage/:bucketId/usage')
|
||||
$stats = $usage = [];
|
||||
$days = $periods[$range];
|
||||
$metrics = [
|
||||
str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES),
|
||||
str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE),
|
||||
str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED),
|
||||
str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES),
|
||||
str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_STORAGE),
|
||||
str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED),
|
||||
];
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $dbForLogs, $bucket, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
$db = ($metric === str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED))
|
||||
$db = ($metric === str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED))
|
||||
? $dbForLogs
|
||||
: $dbForProject;
|
||||
|
||||
|
||||
@@ -123,9 +123,9 @@ App::post('/v1/teams')
|
||||
Permission::delete(Role::team($team->getId(), 'owner')),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'teamId' => $team->getId(),
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'teamInternalId' => $team->getSequence(),
|
||||
'roles' => $roles,
|
||||
'invited' => DateTime::now(),
|
||||
'joined' => DateTime::now(),
|
||||
@@ -595,8 +595,8 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
}
|
||||
|
||||
$membership = $dbForProject->findOne('memberships', [
|
||||
Query::equal('userInternalId', [$invitee->getInternalId()]),
|
||||
Query::equal('teamInternalId', [$team->getInternalId()]),
|
||||
Query::equal('userInternalId', [$invitee->getSequence()]),
|
||||
Query::equal('teamInternalId', [$team->getSequence()]),
|
||||
]);
|
||||
|
||||
$secret = Auth::tokenGenerator();
|
||||
@@ -612,9 +612,9 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
Permission::delete(Role::team($team->getId(), 'owner')),
|
||||
],
|
||||
'userId' => $invitee->getId(),
|
||||
'userInternalId' => $invitee->getInternalId(),
|
||||
'userInternalId' => $invitee->getSequence(),
|
||||
'teamId' => $team->getId(),
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'teamInternalId' => $team->getSequence(),
|
||||
'roles' => $roles,
|
||||
'invited' => DateTime::now(),
|
||||
'joined' => ($isPrivilegedUser || $isAppUser) ? DateTime::now() : null,
|
||||
@@ -842,7 +842,7 @@ App::get('/v1/teams/:teamId/memberships')
|
||||
}
|
||||
|
||||
// Set internal queries
|
||||
$queries[] = Query::equal('teamInternalId', [$team->getInternalId()]);
|
||||
$queries[] = Query::equal('teamInternalId', [$team->getSequence()]);
|
||||
|
||||
/**
|
||||
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
|
||||
@@ -1092,18 +1092,15 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
collection: 'memberships',
|
||||
queries: [
|
||||
Query::contains('roles', ['owner']),
|
||||
Query::equal('teamInternalId', [$team->getInternalId()])
|
||||
Query::equal('teamInternalId', [$team->getSequence()])
|
||||
],
|
||||
max: 2
|
||||
);
|
||||
|
||||
// Is the role change being requested by the user on their own membership?
|
||||
$isCurrentUserAnOwner = $user->getInternalId() === $membership->getAttribute('userInternalId');
|
||||
|
||||
// Prevent role change if there's only one owner left,
|
||||
// the requester is that owner, and the new `$roles` no longer include 'owner'
|
||||
if ($ownersCount === 1 && $isOwner && $isCurrentUserAnOwner && !\in_array('owner', $roles)) {
|
||||
throw new Exception(Exception::MEMBERSHIP_DOWNGRADE_PROHIBITED, 'There must be at least one owner in the organization.');
|
||||
// the requester is that owner, and the new `$roles` no longer include 'owner'!
|
||||
if ($ownersCount === 1 && $isOwner && !\in_array('owner', $roles)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'There must be at least one owner in the organization.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1183,7 +1180,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
throw new Exception(Exception::TEAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($membership->getAttribute('teamInternalId') !== $team->getInternalId()) {
|
||||
if ($membership->getAttribute('teamInternalId') !== $team->getSequence()) {
|
||||
throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH);
|
||||
}
|
||||
|
||||
@@ -1200,7 +1197,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
$user->setAttributes($dbForProject->getDocument('users', $userId)->getArrayCopy()); // Get user
|
||||
}
|
||||
|
||||
if ($membership->getAttribute('userInternalId') !== $user->getInternalId()) {
|
||||
if ($membership->getAttribute('userInternalId') !== $user->getSequence()) {
|
||||
throw new Exception(Exception::TEAM_INVITE_MISMATCH, 'Invite does not belong to current user (' . $user->getAttribute('email') . ')');
|
||||
}
|
||||
|
||||
@@ -1232,7 +1229,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'provider' => Auth::SESSION_PROVIDER_EMAIL,
|
||||
'providerUid' => $user->getAttribute('email'),
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
@@ -1318,12 +1315,10 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
))
|
||||
->param('teamId', '', new UID(), 'Team ID.')
|
||||
->param('membershipId', '', new UID(), 'Membership ID.')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $teamId, string $membershipId, Document $user, Document $project, Response $response, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $membershipId, Response $response, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
|
||||
@@ -1331,9 +1326,9 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
throw new Exception(Exception::TEAM_INVITE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$profile = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
|
||||
$user = $dbForProject->getDocument('users', $membership->getAttribute('userId'));
|
||||
|
||||
if ($profile->isEmpty()) {
|
||||
if ($user->isEmpty()) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -1343,33 +1338,10 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
throw new Exception(Exception::TEAM_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($membership->getAttribute('teamInternalId') !== $team->getInternalId()) {
|
||||
if ($membership->getAttribute('teamInternalId') !== $team->getSequence()) {
|
||||
throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH);
|
||||
}
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
// Quick check:
|
||||
// fetch up to 2 owners to determine if only one exists
|
||||
$ownersCount = $dbForProject->count(
|
||||
collection: 'memberships',
|
||||
queries: [
|
||||
Query::contains('roles', ['owner']),
|
||||
Query::equal('teamInternalId', [$team->getInternalId()])
|
||||
],
|
||||
max: 2
|
||||
);
|
||||
|
||||
// Is the deletion being requested by the user on their own membership and they are also the owner?
|
||||
$isSelfOwner =
|
||||
in_array('owner', $membership->getAttribute('roles')) &&
|
||||
$membership->getAttribute('userInternalId') === $user->getInternalId();
|
||||
|
||||
if ($ownersCount === 1 && $isSelfOwner) {
|
||||
/* Prevent removal if the user is the only owner. */
|
||||
throw new Exception(Exception::MEMBERSHIP_DELETION_PROHIBITED, 'There must be at least one owner in the organization.');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$dbForProject->deleteDocument('memberships', $membership->getId());
|
||||
} catch (AuthorizationException $exception) {
|
||||
@@ -1378,15 +1350,15 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove membership from DB');
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
Authorization::skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('teamId', $team->getId())
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('membershipId', $membership->getId())
|
||||
->setPayload($response->output($membership, Response::MODEL_MEMBERSHIP))
|
||||
;
|
||||
|
||||
@@ -140,7 +140,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => 'email',
|
||||
'identifier' => $email,
|
||||
]));
|
||||
@@ -164,7 +164,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => 'sms',
|
||||
'identifier' => $phone,
|
||||
]));
|
||||
@@ -564,10 +564,10 @@ App::post('/v1/users/:userId/targets')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'providerId' => empty($provider->getId()) ? null : $provider->getId(),
|
||||
'providerInternalId' => $provider->isEmpty() ? null : $provider->getInternalId(),
|
||||
'providerInternalId' => $provider->isEmpty() ? null : $provider->getSequence(),
|
||||
'providerType' => $providerType,
|
||||
'userId' => $userId,
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'identifier' => $identifier,
|
||||
'name' => ($name !== '') ? $name : null,
|
||||
]));
|
||||
@@ -846,7 +846,7 @@ App::get('/v1/users/:userId/memberships')
|
||||
}
|
||||
|
||||
// Set internal queries
|
||||
$queries[] = Query::equal('userInternalId', [$user->getInternalId()]);
|
||||
$queries[] = Query::equal('userInternalId', [$user->getSequence()]);
|
||||
|
||||
$memberships = array_map(function ($membership) use ($dbForProject, $user) {
|
||||
$team = $dbForProject->getDocument('teams', $membership->getAttribute('teamId'));
|
||||
@@ -910,7 +910,7 @@ App::get('/v1/users/:userId/logs')
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getInternalId(), $queries);
|
||||
$logs = $audit->getLogsByUser($user->getSequence(), $queries);
|
||||
|
||||
$output = [];
|
||||
|
||||
@@ -957,7 +957,7 @@ App::get('/v1/users/:userId/logs')
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $audit->countLogsByUser($user->getInternalId(), $queries),
|
||||
'total' => $audit->countLogsByUser($user->getSequence(), $queries),
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
@@ -1396,7 +1396,7 @@ App::patch('/v1/users/:userId/email')
|
||||
// Makes sure this email is not already used in another identity
|
||||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
Query::notEqual('userInternalId', $user->getSequence()),
|
||||
]);
|
||||
if (!$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
@@ -1440,7 +1440,7 @@ App::patch('/v1/users/:userId/email')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => 'email',
|
||||
'identifier' => $email,
|
||||
]));
|
||||
@@ -1529,7 +1529,7 @@ App::patch('/v1/users/:userId/phone')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
],
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'providerType' => 'sms',
|
||||
'identifier' => $number,
|
||||
]));
|
||||
@@ -1711,7 +1711,7 @@ App::patch('/v1/users/:userId/targets/:targetId')
|
||||
|
||||
$target
|
||||
->setAttribute('providerId', $provider->getId())
|
||||
->setAttribute('providerInternalId', $provider->getInternalId());
|
||||
->setAttribute('providerInternalId', $provider->getSequence());
|
||||
}
|
||||
|
||||
if ($name) {
|
||||
@@ -2051,7 +2051,7 @@ App::post('/v1/users/:userId/sessions')
|
||||
[
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'provider' => Auth::SESSION_PROVIDER_SERVER,
|
||||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
@@ -2131,7 +2131,7 @@ App::post('/v1/users/:userId/tokens')
|
||||
$token = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $user->getId(),
|
||||
'userInternalId' => $user->getInternalId(),
|
||||
'userInternalId' => $user->getSequence(),
|
||||
'type' => Auth::TOKEN_TYPE_GENERIC,
|
||||
'secret' => Auth::hash($secret),
|
||||
'expire' => $expire,
|
||||
@@ -2293,8 +2293,8 @@ App::delete('/v1/users/:userId')
|
||||
$clone = clone $user;
|
||||
|
||||
$dbForProject->deleteDocument('users', $userId);
|
||||
DeleteIdentities::delete($dbForProject, Query::equal('userInternalId', [$user->getInternalId()]));
|
||||
DeleteTargets::delete($dbForProject, Query::equal('userInternalId', [$user->getInternalId()]));
|
||||
DeleteIdentities::delete($dbForProject, Query::equal('userInternalId', [$user->getSequence()]));
|
||||
DeleteTargets::delete($dbForProject, Query::equal('userInternalId', [$user->getSequence()]));
|
||||
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_DOCUMENT)
|
||||
|
||||
+20
-27
@@ -78,11 +78,11 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$resourceCollection = $resourceType === "function" ? 'functions' : 'sites';
|
||||
$resourceId = $repository->getAttribute('resourceId');
|
||||
$resource = Authorization::skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId));
|
||||
$resourceInternalId = $resource->getInternalId();
|
||||
$resourceInternalId = $resource->getSequence();
|
||||
|
||||
$deploymentId = ID::unique();
|
||||
$repositoryId = $repository->getId();
|
||||
$repositoryInternalId = $repository->getInternalId();
|
||||
$repositoryInternalId = $repository->getSequence();
|
||||
$providerRepositoryId = $repository->getAttribute('providerRepositoryId');
|
||||
$installationId = $repository->getAttribute('installationId');
|
||||
$installationInternalId = $repository->getAttribute('installationInternalId');
|
||||
@@ -157,7 +157,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
],
|
||||
'installationInternalId' => $installationInternalId,
|
||||
'installationId' => $installationId,
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'projectId' => $project->getId(),
|
||||
'providerRepositoryId' => $providerRepositoryId,
|
||||
'providerBranch' => $providerBranch,
|
||||
@@ -257,7 +257,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
|
||||
$resource = $resource
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource));
|
||||
@@ -273,12 +273,12 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'domain' => $domain,
|
||||
'type' => 'deployment',
|
||||
'trigger' => 'deployment',
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentInternalId' => $deployment->getSequence(),
|
||||
'deploymentResourceType' => 'site',
|
||||
'deploymentResourceId' => $resourceId,
|
||||
'deploymentResourceInternalId' => $resourceInternalId,
|
||||
@@ -293,25 +293,19 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
|
||||
// VCS branch preview
|
||||
if (!empty($providerBranch)) {
|
||||
$branchPrefix = substr($providerBranch, 0, 16);
|
||||
if (strlen($providerBranch) > 16) {
|
||||
$remainingChars = substr($providerBranch, 16);
|
||||
$branchPrefix .= '-' . substr(hash('sha256', $remainingChars), 0, 7);
|
||||
}
|
||||
$resourceProjectHash = substr(hash('sha256', $resource->getId() . $project->getId()), 0, 7);
|
||||
$domain = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
|
||||
$domain = "branch-{$providerBranch}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
|
||||
$ruleId = md5($domain);
|
||||
try {
|
||||
Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'domain' => $domain,
|
||||
'type' => 'deployment',
|
||||
'trigger' => 'deployment',
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentInternalId' => $deployment->getSequence(),
|
||||
'deploymentResourceType' => 'site',
|
||||
'deploymentResourceId' => $resourceId,
|
||||
'deploymentResourceInternalId' => $resourceInternalId,
|
||||
@@ -330,19 +324,19 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
|
||||
// VCS commit preview
|
||||
if (!empty($providerCommitHash)) {
|
||||
$domain = "commit-" . substr($providerCommitHash, 0, 16) . ".{$sitesDomain}";
|
||||
$domain = "commit-{$providerCommitHash}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
|
||||
$ruleId = md5($domain);
|
||||
try {
|
||||
Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'domain' => $domain,
|
||||
'type' => 'deployment',
|
||||
'trigger' => 'deployment',
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentInternalId' => $deployment->getSequence(),
|
||||
'deploymentResourceType' => 'site',
|
||||
'deploymentResourceId' => $resourceId,
|
||||
'deploymentResourceInternalId' => $resourceInternalId,
|
||||
@@ -509,7 +503,7 @@ App::get('/v1/vcs/github/callback')
|
||||
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
|
||||
$owner = $github->getOwnerName($providerInstallationId) ?? '';
|
||||
|
||||
$projectInternalId = $project->getInternalId();
|
||||
$projectInternalId = $project->getSequence();
|
||||
|
||||
$installation = $dbForPlatform->findOne('installations', [
|
||||
Query::equal('providerInstallationId', [$providerInstallationId]),
|
||||
@@ -1005,7 +999,7 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories')
|
||||
if (empty($accessToken) || empty($refreshToken) || empty($accessTokenExpiry)) {
|
||||
$identity = $dbForPlatform->findOne('identities', [
|
||||
Query::equal('provider', ['github']),
|
||||
Query::equal('userInternalId', [$user->getInternalId()]),
|
||||
Query::equal('userInternalId', [$user->getSequence()]),
|
||||
]);
|
||||
if ($identity->isEmpty()) {
|
||||
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
|
||||
@@ -1215,7 +1209,6 @@ App::post('/v1/vcs/github/events')
|
||||
|
||||
if ($event == $github::EVENT_PUSH) {
|
||||
$providerBranchCreated = $parsedPayload["branchCreated"] ?? false;
|
||||
$providerBranchDeleted = $parsedPayload["branchDeleted"] ?? false;
|
||||
$providerBranch = $parsedPayload["branch"] ?? '';
|
||||
$providerBranchUrl = $parsedPayload["branchUrl"] ?? '';
|
||||
$providerRepositoryId = $parsedPayload["repositoryId"] ?? '';
|
||||
@@ -1237,8 +1230,8 @@ App::post('/v1/vcs/github/events')
|
||||
Query::limit(100),
|
||||
]));
|
||||
|
||||
// create new deployment only on push and not when branch is created or deleted
|
||||
if (!$providerBranchCreated && !$providerBranchDeleted) {
|
||||
// create new deployment only on push and not when branch is created
|
||||
if (!$providerBranchCreated) {
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForPlatform, $queueForBuilds, $getProjectDB, $request);
|
||||
}
|
||||
} elseif ($event == $github::EVENT_INSTALLATION) {
|
||||
@@ -1253,7 +1246,7 @@ App::post('/v1/vcs/github/events')
|
||||
|
||||
foreach ($installations as $installation) {
|
||||
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
|
||||
Query::equal('installationInternalId', [$installation->getInternalId()]),
|
||||
Query::equal('installationInternalId', [$installation->getSequence()]),
|
||||
Query::limit(1000)
|
||||
]));
|
||||
|
||||
@@ -1356,7 +1349,7 @@ App::get('/v1/vcs/installations')
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$queries[] = Query::equal('projectInternalId', [$project->getInternalId()]);
|
||||
$queries[] = Query::equal('projectInternalId', [$project->getSequence()]);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = Query::search('search', $search);
|
||||
@@ -1429,7 +1422,7 @@ App::get('/v1/vcs/installations/:installationId')
|
||||
throw new Exception(Exception::INSTALLATION_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($installation->getAttribute('projectInternalId') !== $project->getInternalId()) {
|
||||
if ($installation->getAttribute('projectInternalId') !== $project->getSequence()) {
|
||||
throw new Exception(Exception::INSTALLATION_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -1512,7 +1505,7 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor
|
||||
}
|
||||
|
||||
$repository = Authorization::skip(fn () => $dbForPlatform->getDocument('repositories', $repositoryId, [
|
||||
Query::equal('projectInternalId', [$project->getInternalId()])
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]));
|
||||
|
||||
if ($repository->isEmpty()) {
|
||||
|
||||
+16
-26
@@ -107,7 +107,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
return false;
|
||||
}
|
||||
|
||||
// @luke implement START
|
||||
$projectId = $rule->getAttribute('projectId');
|
||||
$project = Authorization::skip(
|
||||
fn () => $dbForPlatform->getDocument('projects', $projectId)
|
||||
@@ -127,7 +126,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
throw new AppwriteException(AppwriteException::GENERAL_SERVICE_DISABLED, view: $errorView);
|
||||
}
|
||||
}
|
||||
// @luke implement END
|
||||
|
||||
// Skip Appwrite Router for ACME challenge. Nessessary for certificate generation
|
||||
$path = ($swooleRequest->server['request_uri'] ?? '/');
|
||||
@@ -138,7 +136,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
$type = $rule->getAttribute('type', '');
|
||||
|
||||
if ($type === 'deployment') {
|
||||
// @luke implement START
|
||||
if (System::getEnv('_APP_OPTIONS_ROUTER_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
|
||||
if ($request->getProtocol() !== 'https' && $request->getHostname() !== APP_HOSTNAME_INTERNAL) {
|
||||
if ($request->getMethod() !== Request::METHOD_GET) {
|
||||
@@ -147,7 +144,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
return $response->redirect('https://' . $request->getHostname() . $request->getURI());
|
||||
}
|
||||
}
|
||||
// @luke implement END
|
||||
|
||||
/** @var Database $dbForProject */
|
||||
$dbForProject = $getProjectDB($project);
|
||||
@@ -198,7 +194,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
Authorization::skip(fn () => $dbForProject->getDocument('functions', $deployment->getAttribute('resourceId', ''))) :
|
||||
Authorization::skip(fn () => $dbForProject->getDocument('sites', $deployment->getAttribute('resourceId', '')));
|
||||
|
||||
// @luke implement START
|
||||
$isPreview = $type === 'function' ? false : ($rule->getAttribute('trigger', '') !== 'manual');
|
||||
|
||||
$path = ($swooleRequest->server['request_uri'] ?? '/');
|
||||
@@ -280,7 +275,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// @luke implement END
|
||||
|
||||
$body = $swooleRequest->getContent() ?? '';
|
||||
$method = $swooleRequest->server['request_method'];
|
||||
@@ -295,11 +289,9 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
}
|
||||
|
||||
// @luke implement START
|
||||
if ($isResourceBlocked($project, $type === 'function' ? RESOURCE_TYPE_FUNCTIONS : RESOURCE_TYPE_SITES, $resource->getId())) {
|
||||
throw new AppwriteException(AppwriteException::GENERAL_RESOURCE_BLOCKED, view: $errorView);
|
||||
}
|
||||
// @luke implement END
|
||||
|
||||
$version = match ($type) {
|
||||
'function' => $resource->getAttribute('version', 'v2'),
|
||||
@@ -324,10 +316,8 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $resource->getAttribute('runtime', '') . '" is not supported', view: $errorView);
|
||||
}
|
||||
|
||||
// @luke implement START
|
||||
$allowAnyStatus = !\is_null($apiKey) && $apiKey->isDeploymentStatusIgnored();
|
||||
if (!$allowAnyStatus && $deployment->getAttribute('status') !== 'ready') {
|
||||
// @luke implement END
|
||||
$status = $deployment->getAttribute('status');
|
||||
|
||||
switch ($status) {
|
||||
@@ -401,9 +391,9 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
$execution = new Document([
|
||||
'$id' => $executionId,
|
||||
'$permissions' => [],
|
||||
'resourceInternalId' => $resource->getInternalId(),
|
||||
'resourceInternalId' => $resource->getSequence(),
|
||||
'resourceId' => $resource->getId(),
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentInternalId' => $deployment->getSequence(),
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'responseStatusCode' => 0,
|
||||
'responseHeaders' => [],
|
||||
@@ -438,7 +428,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
$vars = [];
|
||||
|
||||
// V2 vars
|
||||
// @luke implement START
|
||||
if ($version === 'v2') {
|
||||
$vars = \array_merge($vars, [
|
||||
'APPWRITE_FUNCTION_TRIGGER' => $headers['x-appwrite-trigger'] ?? '',
|
||||
@@ -447,7 +436,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
'APPWRITE_FUNCTION_JWT' => $headers['x-appwrite-user-jwt'] ?? ''
|
||||
]);
|
||||
}
|
||||
// @luke implement END
|
||||
|
||||
// Shared vars
|
||||
foreach ($resource->getAttribute('varsProject', []) as $var) {
|
||||
@@ -519,12 +507,10 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
'function' => $resource->getAttribute('version', 'v2'),
|
||||
'site' => 'v5',
|
||||
};
|
||||
// @luke implement START
|
||||
$entrypoint = match ($type) {
|
||||
'function' => $deployment->getAttribute('entrypoint', ''),
|
||||
'site' => '',
|
||||
};
|
||||
// @luke implement END
|
||||
|
||||
if ($type === 'function') {
|
||||
$runtimeEntrypoint = match ($version) {
|
||||
@@ -601,7 +587,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
|
||||
// Branded error pages (when developer left body empty)
|
||||
// @luke implement START
|
||||
if ($executionResponse['statusCode'] >= 400 && empty($executionResponse['body'])) {
|
||||
$layout = new View($errorView);
|
||||
$layout
|
||||
@@ -618,7 +603,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
}
|
||||
}
|
||||
// @luke implement END
|
||||
|
||||
$headersFiltered = [];
|
||||
foreach ($executionResponse['headers'] as $key => $value) {
|
||||
@@ -708,11 +692,11 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
|
||||
$metricTypeExecutions = str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_EXECUTIONS);
|
||||
$metricTypeIdExecutions = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS);
|
||||
$metricTypeIdExecutions = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS);
|
||||
$metricTypeExecutionsCompute = str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_EXECUTIONS_COMPUTE);
|
||||
$metricTypeIdExecutionsCompute = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE);
|
||||
$metricTypeIdExecutionsCompute = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE);
|
||||
$metricTypeExecutionsMbSeconds = str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_EXECUTIONS_MB_SECONDS);
|
||||
$metricTypeIdExecutionsMBSeconds = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
|
||||
$metricTypeIdExecutionsMBSeconds = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
|
||||
if ($deployment->getAttribute('resourceType') === 'sites') {
|
||||
$queueForStatsUsage
|
||||
->disableMetric(METRIC_NETWORK_REQUESTS)
|
||||
@@ -735,9 +719,9 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
->addMetric(METRIC_SITES_REQUESTS, 1)
|
||||
->addMetric(METRIC_SITES_INBOUND, $request->getSize() + $fileSize)
|
||||
->addMetric(METRIC_SITES_OUTBOUND, $response->getSize())
|
||||
->addMetric(str_replace('{siteInternalId}', $resource->getInternalId(), METRIC_SITES_ID_REQUESTS), 1)
|
||||
->addMetric(str_replace('{siteInternalId}', $resource->getInternalId(), METRIC_SITES_ID_INBOUND), $request->getSize() + $fileSize)
|
||||
->addMetric(str_replace('{siteInternalId}', $resource->getInternalId(), METRIC_SITES_ID_OUTBOUND), $response->getSize())
|
||||
->addMetric(str_replace('{siteInternalId}', $resource->getSequence(), METRIC_SITES_ID_REQUESTS), 1)
|
||||
->addMetric(str_replace('{siteInternalId}', $resource->getSequence(), METRIC_SITES_ID_INBOUND), $request->getSize() + $fileSize)
|
||||
->addMetric(str_replace('{siteInternalId}', $resource->getSequence(), METRIC_SITES_ID_OUTBOUND), $response->getSize())
|
||||
;
|
||||
}
|
||||
|
||||
@@ -765,6 +749,12 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
return false;
|
||||
} elseif ($type === 'redirect') {
|
||||
$url = $rule->getAttribute('redirectUrl', '');
|
||||
|
||||
$query = ($swooleRequest->server['query_string'] ?? '');
|
||||
if (!empty($query)) {
|
||||
$url .= '?' . $query;
|
||||
}
|
||||
|
||||
$response->redirect($url, \intval($rule->getAttribute('redirectStatusCode', 301)));
|
||||
return true;
|
||||
} else {
|
||||
@@ -924,7 +914,7 @@ App::init()
|
||||
'type' => 'api',
|
||||
'status' => 'verifying',
|
||||
'projectId' => $console->getId(),
|
||||
'projectInternalId' => $console->getInternalId(),
|
||||
'projectInternalId' => $console->getSequence(),
|
||||
'search' => implode(' ', [$ruleId, $domain->get()]),
|
||||
'owner' => $owner,
|
||||
'region' => $console->getAttribute('region')
|
||||
@@ -974,7 +964,7 @@ App::init()
|
||||
)[0] ?? new Document();
|
||||
}
|
||||
|
||||
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getInternalId()) {
|
||||
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getSequence()) {
|
||||
$refDomainOrigin = $origin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ App::post('/v1/mock/api-key-unprefixed')
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'projectId' => $project->getId(),
|
||||
'name' => 'Outdated key',
|
||||
'scopes' => $scopes,
|
||||
@@ -235,7 +235,7 @@ App::get('/v1/mock/github/callback')
|
||||
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
|
||||
$owner = $github->getOwnerName($providerInstallationId) ?? '';
|
||||
|
||||
$projectInternalId = $project->getInternalId();
|
||||
$projectInternalId = $project->getSequence();
|
||||
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
|
||||
|
||||
@@ -574,7 +574,7 @@ App::init()
|
||||
$bucketId = $parts[1] ?? null;
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
@@ -593,12 +593,12 @@ App::init()
|
||||
$fileId = $parts[1] ?? null;
|
||||
|
||||
if ($fileSecurity && !$valid && !$isToken) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -309,7 +309,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
||||
'orders' => $index['orders'],
|
||||
]), $files['indexes']);
|
||||
|
||||
$dbForPlatform->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes);
|
||||
$dbForPlatform->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes);
|
||||
}
|
||||
|
||||
if (Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots')->isEmpty())) {
|
||||
@@ -357,7 +357,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
||||
'orders' => $index['orders'],
|
||||
]), $files['indexes']);
|
||||
|
||||
Authorization::skip(fn () => $dbForPlatform->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes));
|
||||
Authorization::skip(fn () => $dbForPlatform->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
use Utopia\Config\Config;
|
||||
|
||||
require_once __DIR__ . '/../config/storage/resource_limits.php';
|
||||
|
||||
Config::load('template-runtimes', __DIR__ . '/../config/template-runtimes.php');
|
||||
Config::load('events', __DIR__ . '/../config/events.php');
|
||||
Config::load('auth', __DIR__ . '/../config/auth.php');
|
||||
|
||||
@@ -51,6 +51,7 @@ const APP_DATABASE_TIMEOUT_MILLISECONDS_API = 15 * 1000; // 15 seconds
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER = 300 * 1000; // 5 minutes
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_TASK = 300 * 1000; // 5 minutes
|
||||
const APP_DATABASE_QUERY_MAX_VALUES = 500;
|
||||
const APP_DATABASE_ENCRYPT_SIZE_MIN = 150;
|
||||
const APP_STORAGE_UPLOADS = '/storage/uploads';
|
||||
const APP_STORAGE_SITES = '/storage/sites';
|
||||
const APP_STORAGE_FUNCTIONS = '/storage/functions';
|
||||
|
||||
@@ -71,18 +71,27 @@ Database::addFilter(
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
$attributes = $database->find('attributes', [
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('collectionInternalId', [$document->getSequence()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getLimitForAttributes()),
|
||||
]);
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) {
|
||||
$options = $attribute->getAttribute('options');
|
||||
foreach ($options as $key => $value) {
|
||||
$attribute->setAttribute($key, $value);
|
||||
}
|
||||
$attribute->removeAttribute('options');
|
||||
$attributeType = $attribute->getAttribute('type');
|
||||
|
||||
switch ($attributeType) {
|
||||
case Database::VAR_RELATIONSHIP:
|
||||
$options = $attribute->getAttribute('options');
|
||||
foreach ($options as $key => $value) {
|
||||
$attribute->setAttribute($key, $value);
|
||||
}
|
||||
$attribute->removeAttribute('options');
|
||||
break;
|
||||
|
||||
case Database::VAR_STRING:
|
||||
$filters = $attribute->getAttribute('filters', []);
|
||||
$attribute->setAttribute('encrypt', in_array('encrypt', $filters));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +107,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('indexes', [
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('collectionInternalId', [$document->getSequence()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getLimitForIndexes()),
|
||||
]);
|
||||
@@ -113,7 +122,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('platforms', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
@@ -127,7 +136,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('keys', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
@@ -141,7 +150,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('devKeys', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
@@ -155,7 +164,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('webhooks', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
@@ -168,7 +177,7 @@ Database::addFilter(
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database->find('sessions', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
@@ -182,7 +191,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('tokens', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
@@ -196,7 +205,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('challenges', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
@@ -210,7 +219,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('authenticators', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
@@ -224,7 +233,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('memberships', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
@@ -238,7 +247,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('variables', [
|
||||
Query::equal('resourceInternalId', [$document->getInternalId()]),
|
||||
Query::equal('resourceInternalId', [$document->getSequence()]),
|
||||
Query::equal('resourceType', ['function', 'site']),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
@@ -316,7 +325,7 @@ Database::addFilter(
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('targets', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY)
|
||||
]));
|
||||
}
|
||||
@@ -331,13 +340,13 @@ Database::addFilter(
|
||||
$targetIds = Authorization::skip(fn () => \array_map(
|
||||
fn ($document) => $document->getAttribute('targetInternalId'),
|
||||
$database->find('subscribers', [
|
||||
Query::equal('topicInternalId', [$document->getInternalId()]),
|
||||
Query::equal('topicInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBSCRIBERS_SUBQUERY)
|
||||
])
|
||||
));
|
||||
if (\count($targetIds) > 0) {
|
||||
return $database->skipValidation(fn () => $database->find('targets', [
|
||||
Query::equal('$internalId', $targetIds)
|
||||
Query::equal('$sequence', $targetIds)
|
||||
]));
|
||||
}
|
||||
return [];
|
||||
|
||||
+32
-35
@@ -52,7 +52,6 @@ use Utopia\Storage\Device\S3;
|
||||
use Utopia\Storage\Device\Wasabi;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Telemetry\Adapter as Telemetry;
|
||||
use Utopia\Telemetry\Adapter\None as NoTelemetry;
|
||||
use Utopia\Validator\Hostname;
|
||||
use Utopia\Validator\WhiteList;
|
||||
@@ -348,13 +347,13 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
return $database;
|
||||
@@ -401,13 +400,13 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -431,7 +430,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
|
||||
return function (?Document $project = null) use ($pools, $cache, &$database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
$database->setTenant($project->getSequence());
|
||||
return $database;
|
||||
}
|
||||
|
||||
@@ -446,7 +445,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
|
||||
// set tenant
|
||||
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
$database->setTenant($project->getSequence());
|
||||
}
|
||||
|
||||
return $database;
|
||||
@@ -455,7 +454,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
|
||||
App::setResource('telemetry', fn () => new NoTelemetry());
|
||||
|
||||
App::setResource('cache', function (Group $pools, Telemetry $telemetry) {
|
||||
App::setResource('cache', function (Group $pools) {
|
||||
$list = Config::getParam('pools-cache', []);
|
||||
$adapters = [];
|
||||
|
||||
@@ -463,10 +462,8 @@ App::setResource('cache', function (Group $pools, Telemetry $telemetry) {
|
||||
$adapters[] = new CachePool($pools->get($value));
|
||||
}
|
||||
|
||||
$cache = new Cache(new Sharding($adapters));
|
||||
$cache->setTelemetry($telemetry);
|
||||
return $cache;
|
||||
}, ['pools', 'telemetry']);
|
||||
return new Cache(new Sharding($adapters));
|
||||
}, ['pools']);
|
||||
|
||||
App::setResource('redis', function () {
|
||||
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
|
||||
@@ -489,24 +486,24 @@ App::setResource('timelimit', function (\Redis $redis) {
|
||||
};
|
||||
}, ['redis']);
|
||||
|
||||
App::setResource('deviceForLocal', function (Telemetry $telemetry) {
|
||||
return new Device\Telemetry($telemetry, new Local());
|
||||
}, ['telemetry']);
|
||||
App::setResource('deviceForFiles', function ($project, Telemetry $telemetry) {
|
||||
return new Device\Telemetry($telemetry, getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
App::setResource('deviceForSites', function ($project, Telemetry $telemetry) {
|
||||
return new Device\Telemetry($telemetry, getDevice(APP_STORAGE_SITES . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
App::setResource('deviceForImports', function ($project, Telemetry $telemetry) {
|
||||
return new Device\Telemetry($telemetry, getDevice(APP_STORAGE_IMPORTS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
App::setResource('deviceForFunctions', function ($project, Telemetry $telemetry) {
|
||||
return new Device\Telemetry($telemetry, getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
App::setResource('deviceForBuilds', function ($project, Telemetry $telemetry) {
|
||||
return new Device\Telemetry($telemetry, getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
App::setResource('deviceForLocal', function () {
|
||||
return new Local();
|
||||
});
|
||||
App::setResource('deviceForFiles', function ($project) {
|
||||
return getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
App::setResource('deviceForSites', function ($project) {
|
||||
return getDevice(APP_STORAGE_SITES . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
App::setResource('deviceForImports', function ($project) {
|
||||
return getDevice(APP_STORAGE_IMPORTS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
App::setResource('deviceForFunctions', function ($project) {
|
||||
return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
App::setResource('deviceForBuilds', function ($project) {
|
||||
return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
function getDevice(string $root, string $connection = ''): Device
|
||||
{
|
||||
@@ -839,7 +836,7 @@ App::setResource('team', function (Document $project, Database $dbForPlatform, A
|
||||
|
||||
$team = Authorization::skip(function () use ($dbForPlatform, $teamInternalId) {
|
||||
return $dbForPlatform->findOne('teams', [
|
||||
Query::equal('$internalId', [$teamInternalId]),
|
||||
Query::equal('$sequence', [$teamInternalId]),
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -918,10 +915,10 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) {
|
||||
|
||||
return match ($token->getAttribute('resourceType')) {
|
||||
TOKENS_RESOURCE_TYPE_FILES => (function () use ($token, $dbForProject) {
|
||||
$internalIds = explode(':', $token->getAttribute('resourceInternalId'));
|
||||
$sequences = explode(':', $token->getAttribute('resourceInternalId'));
|
||||
$ids = explode(':', $token->getAttribute('resourceId'));
|
||||
|
||||
if (count($internalIds) !== 2 || count($ids) !== 2) {
|
||||
if (count($sequences) !== 2 || count($ids) !== 2) {
|
||||
return new Document([]);
|
||||
}
|
||||
|
||||
@@ -934,8 +931,8 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) {
|
||||
return new Document([
|
||||
'bucketId' => $ids[0],
|
||||
'fileId' => $ids[1],
|
||||
'bucketInternalId' => $internalIds[0],
|
||||
'fileInternalId' => $internalIds[1],
|
||||
'bucketInternalId' => $sequences[0],
|
||||
'fileInternalId' => $sequences[1],
|
||||
]);
|
||||
})(),
|
||||
|
||||
|
||||
+5
-5
@@ -79,8 +79,8 @@ if (!function_exists('getProjectDB')) {
|
||||
|
||||
static $databases = [];
|
||||
|
||||
if (isset($databases[$project->getInternalId()])) {
|
||||
return $databases[$project->getInternalId()];
|
||||
if (isset($databases[$project->getSequence()])) {
|
||||
return $databases[$project->getSequence()];
|
||||
}
|
||||
|
||||
/** @var Group $pools */
|
||||
@@ -105,20 +105,20 @@ if (!function_exists('getProjectDB')) {
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$database
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId());
|
||||
|
||||
return $databases[$project->getInternalId()] = $database;
|
||||
return $databases[$project->getSequence()] = $database;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +151,37 @@
|
||||
<div class="center"><a href="/"><button>Go to homepage</button></a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="brand">
|
||||
<p>Powered by</p>
|
||||
<svg class="logo-dark" width="110" height="20" viewBox="0 0 110 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M31.8649 16.2461C33.6492 16.2461 34.5511 15.3184 34.9433 14.6867H35.1197C35.1981 15.3578 35.6687 15.9895 36.5903 15.9895H38.3353V14.0156H37.8843C37.5706 14.0156 37.4138 13.838 37.4138 13.5617V5.64661H35.1001V6.90986H34.9236C34.4727 6.27823 33.5315 5.39001 31.8061 5.39001C29.0611 5.39001 27.022 7.67965 27.022 10.818C27.022 13.9564 29.1003 16.2461 31.8649 16.2461ZM32.2767 13.9959C30.6493 13.9959 29.3748 12.7919 29.3748 10.8378C29.3748 8.92316 30.6101 7.62044 32.2571 7.62044C33.8256 7.62044 35.1393 8.78499 35.1393 10.8378C35.1393 12.5945 34.0217 13.9959 32.2767 13.9959Z" fill="#EDEDF0" />
|
||||
<path d="M39.7013 20H42.0149V14.6867H42.1914C42.6227 15.3184 43.5443 16.2461 45.3677 16.2461C48.1127 16.2461 50.1127 13.9169 50.1127 10.818C50.1127 7.69939 47.9755 5.39001 45.2109 5.39001C43.4462 5.39001 42.5835 6.35719 42.1718 6.89012H41.9953V5.64661H39.7013V20ZM44.8776 14.0551C43.2894 14.0551 41.9757 12.8708 41.9757 10.818C41.9757 9.06133 43.0933 7.58096 44.8383 7.58096C46.4657 7.58096 47.7402 8.86395 47.7402 10.818C47.7402 12.7326 46.5049 14.0551 44.8776 14.0551Z" fill="#EDEDF0" />
|
||||
<path d="M51.3065 20H53.6202V14.6867H53.7966C54.228 15.3184 55.1495 16.2461 56.973 16.2461C59.718 16.2461 61.5273 13.9169 61.5273 10.818C61.5273 7.69939 59.5807 5.39001 56.8161 5.39001C55.0515 5.39001 54.1888 6.35719 53.777 6.89012H53.6005V5.64661H51.3065V20ZM56.4828 14.0551C54.8946 14.0551 53.5809 12.8708 53.5809 10.818C53.5809 9.06133 54.6985 7.58096 56.4436 7.58096C58.071 7.58096 59.3454 8.86395 59.3454 10.818C59.3454 12.7326 58.1102 14.0551 56.4828 14.0551Z" fill="#EDEDF0" />
|
||||
<path d="M64.5857 16.2296H67.8601L69.7227 8.11721H69.8404L71.7031 16.2296H74.9579L77.5642 5.88678H75.2323L73.3697 14.0189H73.1932L71.3305 5.88678H68.2522L66.3699 14.0189H66.1935L64.3504 5.88678H61.8799L64.5857 16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M78.7363 16.2296H81.0499V11.1174C81.0499 9.16334 81.9519 7.9593 83.6381 7.9593H84.6576V5.63019H83.893C82.5793 5.63019 81.5793 6.53815 81.1872 7.40663H81.0303V5.88678H78.7363V16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M96.1391 16.2296H97.943V14.1571H96.1587C95.4529 14.1571 95.1588 13.8413 95.1588 13.111V7.93956H98.0606V5.88678H95.1588V2.98526H92.9628V5.88678H91.0413V7.93956H92.8255V13.1307C92.8255 15.3217 94.1392 16.2296 96.1391 16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M104.15 16.2461C106.287 16.2461 108.17 15.1802 108.836 13.0287L106.719 12.5155C106.346 13.6603 105.268 14.2525 104.13 14.2525C102.444 14.2525 101.327 13.1472 101.307 11.4102H109.091V10.7588C109.091 7.67965 107.189 5.39001 104.052 5.39001C101.287 5.39001 98.915 7.58096 98.915 10.8378C98.915 13.9959 101.013 16.2461 104.15 16.2461ZM101.327 9.71269C101.464 8.46918 102.581 7.42305 104.052 7.42305C105.464 7.42305 106.621 8.31128 106.738 9.71269H101.327Z" fill="#EDEDF0" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.0125 16.2296H87.6989V7.93956H85.895V5.88678H90.0125V16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M88.6834 4.45145C89.5265 4.45145 90.154 3.81983 90.154 2.99082C90.154 2.18155 89.5265 1.54993 88.6834 1.54993C87.8403 1.54993 87.2129 2.18155 87.2129 2.99082C87.2129 3.81983 87.8403 4.45145 88.6834 4.45145Z" fill="#EDEDF0" />
|
||||
<path d="M20.2007 13.6935V18.258H8.88588C5.5894 18.258 2.71111 16.4222 1.17116 13.6935C0.947288 13.2968 0.751353 12.8806 0.586995 12.4486C0.26435 11.6021 0.0615332 10.6938 0 9.74603V8.51195C0.0133592 8.30074 0.03441 8.09119 0.0619381 7.88413C0.118209 7.45921 0.203222 7.04343 0.314953 6.63926C1.37195 2.80758 4.8089 0 8.88588 0C12.9629 0 16.3994 2.80758 17.4564 6.63926H12.6184C11.8241 5.39025 10.4493 4.5645 8.88588 4.5645C7.32245 4.5645 5.94767 5.39025 5.15341 6.63926C4.91132 7.01895 4.72349 7.43764 4.60042 7.88413C4.49112 8.27999 4.43282 8.69744 4.43282 9.12899C4.43282 10.4373 4.96962 11.6166 5.83027 12.4486C6.62778 13.2209 7.70299 13.6935 8.88588 13.6935H20.2007Z" fill="#FD366E" />
|
||||
<path d="M20.2006 7.88412V12.4486H11.9414C12.8021 11.6166 13.3389 10.4373 13.3389 9.12899C13.3389 8.69744 13.2806 8.27999 13.1713 7.88412H20.2006Z" fill="#FD366E" />
|
||||
</svg>
|
||||
<svg class="logo-light" width="110" height="20" viewBox="0 0 110 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M31.8648 16.2461C33.649 16.2461 34.5509 15.3184 34.9431 14.6867H35.1195C35.198 15.3578 35.6685 15.9895 36.5901 15.9895H38.3351V14.0156H37.8841C37.5704 14.0156 37.4136 13.838 37.4136 13.5617V5.64661H35.0999V6.90986H34.9235C34.4725 6.27823 33.5314 5.39001 31.8059 5.39001C29.0609 5.39001 27.0218 7.67965 27.0218 10.818C27.0218 13.9564 29.1001 16.2461 31.8648 16.2461ZM32.2765 13.9959C30.6491 13.9959 29.3746 12.7919 29.3746 10.8378C29.3746 8.92316 30.6099 7.62044 32.2569 7.62044C33.8255 7.62044 35.1391 8.78499 35.1391 10.8378C35.1391 12.5945 34.0215 13.9959 32.2765 13.9959Z" fill="#2D2D31" />
|
||||
<path d="M39.7011 20H42.0147V14.6867H42.1912C42.6226 15.3184 43.5441 16.2461 45.3676 16.2461C48.1126 16.2461 50.1125 13.9169 50.1125 10.818C50.1125 7.69939 47.9753 5.39001 45.2107 5.39001C43.4461 5.39001 42.5833 6.35719 42.1716 6.89012H41.9951V5.64661H39.7011V20ZM44.8774 14.0551C43.2892 14.0551 41.9755 12.8708 41.9755 10.818C41.9755 9.06133 43.0931 7.58096 44.8382 7.58096C46.4656 7.58096 47.74 8.86395 47.74 10.818C47.74 12.7326 46.5048 14.0551 44.8774 14.0551Z" fill="#2D2D31" />
|
||||
<path d="M51.3063 20H53.62V14.6867H53.7964C54.2278 15.3184 55.1493 16.2461 56.9728 16.2461C59.7178 16.2461 61.5271 13.9169 61.5271 10.818C61.5271 7.69939 59.5805 5.39001 56.8159 5.39001C55.0513 5.39001 54.1886 6.35719 53.7768 6.89012H53.6004V5.64661H51.3063V20ZM56.4826 14.0551C54.8944 14.0551 53.5808 12.8708 53.5808 10.818C53.5808 9.06133 54.6984 7.58096 56.4434 7.58096C58.0708 7.58096 59.3453 8.86395 59.3453 10.818C59.3453 12.7326 58.11 14.0551 56.4826 14.0551Z" fill="#2D2D31" />
|
||||
<path d="M64.5855 16.2296H67.8599L69.7226 8.11721H69.8402L71.7029 16.2296H74.9577L77.564 5.88678H75.2322L73.3695 14.0189H73.193L71.3303 5.88678H68.252L66.3697 14.0189H66.1933L64.3502 5.88678H61.8797L64.5855 16.2296Z" fill="#2D2D31" />
|
||||
<path d="M78.7361 16.2296H81.0498V11.1174C81.0498 9.16334 81.9517 7.9593 83.6379 7.9593H84.6575V5.63019H83.8928C82.5791 5.63019 81.5791 6.53815 81.187 7.40663H81.0301V5.88678H78.7361V16.2296Z" fill="#2D2D31" />
|
||||
<path d="M96.1389 16.2296H97.9428V14.1571H96.1585C95.4527 14.1571 95.1586 13.8413 95.1586 13.111V7.93956H98.0604V5.88678H95.1586V2.98526H92.9626V5.88678H91.0411V7.93956H92.8253V13.1307C92.8253 15.3217 94.139 16.2296 96.1389 16.2296Z" fill="#2D2D31" />
|
||||
<path d="M104.15 16.2461C106.287 16.2461 108.169 15.1802 108.836 13.0287L106.718 12.5155C106.346 13.6603 105.268 14.2525 104.13 14.2525C102.444 14.2525 101.326 13.1472 101.307 11.4102H109.091V10.7588C109.091 7.67965 107.189 5.39001 104.052 5.39001C101.287 5.39001 98.9148 7.58096 98.9148 10.8378C98.9148 13.9959 101.013 16.2461 104.15 16.2461ZM101.326 9.71269C101.464 8.46918 102.581 7.42305 104.052 7.42305C105.464 7.42305 106.62 8.31128 106.738 9.71269H101.326Z" fill="#2D2D31" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.0123 16.2296H87.6987V7.93956H85.8948V5.88678H90.0123V16.2296Z" fill="#2D2D31" />
|
||||
<path d="M88.6835 4.45145C89.5266 4.45145 90.154 3.81983 90.154 2.99082C90.154 2.18155 89.5266 1.54993 88.6835 1.54993C87.8404 1.54993 87.213 2.18155 87.213 2.99082C87.213 3.81983 87.8404 4.45145 88.6835 4.45145Z" fill="#2D2D31" />
|
||||
<path d="M20.2007 13.6935V18.258H8.88588C5.5894 18.258 2.71111 16.4222 1.17116 13.6935C0.947288 13.2968 0.751353 12.8806 0.586995 12.4486C0.26435 11.6021 0.0615332 10.6938 0 9.74603V8.51195C0.0133592 8.30074 0.03441 8.09119 0.0619381 7.88413C0.118209 7.45921 0.203222 7.04343 0.314953 6.63926C1.37195 2.80758 4.8089 0 8.88588 0C12.9629 0 16.3994 2.80758 17.4564 6.63926H12.6184C11.8241 5.39025 10.4493 4.5645 8.88588 4.5645C7.32245 4.5645 5.94767 5.39025 5.15341 6.63926C4.91132 7.01895 4.72349 7.43764 4.60042 7.88413C4.49112 8.27999 4.43282 8.69744 4.43282 9.12899C4.43282 10.4373 4.96962 11.6166 5.83027 12.4486C6.62778 13.2209 7.70299 13.6935 8.88588 13.6935H20.2007Z" fill="#FD366E" />
|
||||
<path d="M20.2007 7.88412V12.4486H11.9415C12.8022 11.6166 13.339 10.4373 13.339 9.12899C13.339 8.69744 13.2807 8.27999 13.1714 7.88412H20.2007Z" fill="#FD366E" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -512,6 +512,36 @@ switch ($type) {
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div x-show="page === 'error'" class="brand">
|
||||
<p>Powered by</p>
|
||||
<svg class="logo-dark" width="110" height="20" viewBox="0 0 110 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M31.8649 16.2461C33.6492 16.2461 34.5511 15.3184 34.9433 14.6867H35.1197C35.1981 15.3578 35.6687 15.9895 36.5903 15.9895H38.3353V14.0156H37.8843C37.5706 14.0156 37.4138 13.838 37.4138 13.5617V5.64661H35.1001V6.90986H34.9236C34.4727 6.27823 33.5315 5.39001 31.8061 5.39001C29.0611 5.39001 27.022 7.67965 27.022 10.818C27.022 13.9564 29.1003 16.2461 31.8649 16.2461ZM32.2767 13.9959C30.6493 13.9959 29.3748 12.7919 29.3748 10.8378C29.3748 8.92316 30.6101 7.62044 32.2571 7.62044C33.8256 7.62044 35.1393 8.86395 35.1393 10.8378C35.1393 12.5945 34.0217 13.9959 32.2767 13.9959Z" fill="#EDEDF0" />
|
||||
<path d="M39.7013 20H42.0149V14.6867H42.1914C42.6227 15.3184 43.5443 16.2461 45.3677 16.2461C48.1127 16.2461 50.1127 13.9169 50.1127 10.818C50.1127 7.69939 47.9755 5.39001 45.2109 5.39001C43.4462 5.39001 42.5835 6.35719 42.1718 6.89012H41.9953V5.63019H39.7013V20ZM44.8776 14.0551C43.2894 14.0551 41.9757 12.8708 41.9757 10.818C41.9757 9.06133 43.0933 7.58096 44.8383 7.58096C46.4657 7.58096 47.7402 8.86395 47.7402 10.818C47.7402 12.7326 46.5049 14.0551 44.8776 14.0551Z" fill="#EDEDF0" />
|
||||
<path d="M51.3065 20H53.6202V14.6867H53.7966C54.228 15.3184 55.1495 16.2461 56.973 16.2461C59.718 16.2461 61.5273 13.9169 61.5273 10.818C61.5273 7.69939 59.5807 5.39001 56.8161 5.39001C55.0515 5.39001 54.1888 6.35719 53.777 6.89012H53.6005V5.64661H51.3065V20ZM56.4828 14.0551C54.8946 14.0551 53.5809 12.8708 53.5809 10.818C53.5809 9.06133 54.6985 7.58096 56.4436 7.58096C58.071 7.58096 59.3454 8.86395 59.3454 10.818C59.3454 12.7326 58.1102 14.0551 56.4828 14.0551Z" fill="#EDEDF0" />
|
||||
<path d="M64.5857 16.2296H67.8601L69.7227 8.11721H69.8404L71.7031 16.2296H74.9579L77.5642 5.88678H75.2323L73.3697 14.0189H73.1932L71.3305 5.88678H68.2522L66.3699 14.0189H66.1935L64.3504 5.88678H61.8799L64.5857 16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M78.7363 16.2296H81.0499V11.1174C81.0499 9.16334 81.9519 7.9593 83.6381 7.9593H84.6576V5.63019H83.893C82.5793 5.63019 81.5793 6.53815 81.1872 7.40663H81.0303V5.88678H78.7363V16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M96.1391 16.2296H97.943V14.1571H96.1587C95.4529 14.1571 95.1588 13.8413 95.1588 13.111V7.93956H98.0606V5.88678H95.1588V2.98526H92.9628V5.88678H91.0413V7.93956H92.8255V13.1307C92.8255 15.3217 94.1392 16.2296 96.1391 16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M104.15 16.2461C106.287 16.2461 108.17 15.1802 108.836 13.0287L106.719 12.5155C106.346 13.6603 105.268 14.2525 104.13 14.2525C102.444 14.2525 101.327 13.1472 101.307 11.4102H109.091V10.7588C109.091 7.67965 107.189 5.39001 104.052 5.39001C101.287 5.39001 98.915 7.58096 98.915 10.8378C98.915 13.9959 101.013 16.2461 104.15 16.2461ZM101.327 9.71269C101.464 8.46918 102.581 7.42305 104.052 7.42305C105.464 7.42305 106.621 8.31128 106.738 9.71269H101.327Z" fill="#EDEDF0" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.0125 16.2296H87.6989V7.93956H85.895V5.88678H90.0125V16.2296Z" fill="#EDEDF0" />
|
||||
<path d="M88.6834 4.45145C89.5265 4.45145 90.154 3.81983 90.154 2.99082C90.154 2.18155 89.5265 1.54993 88.6834 1.54993C87.8403 1.54993 87.2129 2.18155 87.2129 2.99082C87.2129 3.81983 87.8403 4.45145 88.6834 4.45145Z" fill="#EDEDF0" />
|
||||
<path d="M20.2007 13.6935V18.258H8.88588C5.5894 18.258 2.71111 16.4222 1.17116 13.6935C0.947288 13.2968 0.751353 12.8806 0.586995 12.4486C0.26435 11.6021 0.0615332 10.6938 0 9.74603V8.51195C0.0133592 8.30074 0.03441 8.09119 0.0619381 7.88413C0.118209 7.45921 0.203222 7.04343 0.314953 6.63926C1.37195 2.80758 4.8089 0 8.88588 0C12.9629 0 16.3994 2.80758 17.4564 6.63926H12.6184C11.8241 5.39025 10.4493 4.5645 8.88588 4.5645C7.32245 4.5645 5.94767 5.39025 5.15341 6.63926C4.91132 7.01895 4.72349 7.43764 4.60042 7.88413C4.49112 8.27999 4.43282 8.69744 4.43282 9.12899C4.43282 10.4373 4.96962 11.6166 5.83027 12.4486C6.62778 13.2209 7.70299 13.6935 8.88588 13.6935H20.2007Z" fill="#FD366E" />
|
||||
<path d="M20.2006 7.88412V12.4486H11.9414C12.8021 11.6166 13.3389 10.4373 13.3389 9.12899C13.3389 8.69744 13.2806 8.27999 13.1713 7.88412H20.2006Z" fill="#FD366E" />
|
||||
</svg>
|
||||
<svg class="logo-light" width="110" height="20" viewBox="0 0 110 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M31.8648 16.2461C33.649 16.2461 34.5509 15.3184 34.9431 14.6867H35.1195C35.198 15.3578 35.6685 15.9895 36.5901 15.9895H38.3351V14.0156H37.8841C37.5704 14.0156 37.4136 13.838 37.4136 13.5617V5.64661H35.0999V6.90986H34.9235C34.4725 6.27823 33.5314 5.39001 31.8059 5.39001C29.0609 5.39001 27.0218 7.67965 27.0218 10.818C27.0218 13.9564 29.1001 16.2461 31.8648 16.2461ZM32.2765 13.9959C30.6491 13.9959 29.3746 12.7919 29.3746 10.8378C29.3746 8.92316 30.6099 7.62044 32.2569 7.62044C33.8255 7.62044 35.1391 8.78499 35.1391 10.8378C35.1391 12.5945 34.0215 13.9959 32.2765 13.9959Z" fill="#2D2D31" />
|
||||
<path d="M39.7011 20H42.0147V14.6867H42.1912C42.6226 15.3184 43.5441 16.2461 45.3676 16.2461C48.1126 16.2461 50.1125 13.9169 50.1125 10.818C50.1125 7.69939 47.9753 5.39001 45.2107 5.39001C43.4461 5.39001 42.5833 6.35719 42.1716 6.89012H41.9951V5.64661H39.7011V20ZM44.8774 14.0551C43.2892 14.0551 41.9755 12.8708 41.9755 10.818C41.9755 9.06133 43.0931 7.58096 44.8382 7.58096C46.4656 7.58096 47.74 8.86395 47.74 10.818C47.74 12.7326 46.5048 14.0551 44.8774 14.0551Z" fill="#2D2D31" />
|
||||
<path d="M51.3063 20H53.62V14.6867H53.7964C54.2278 15.3184 55.1493 16.2461 56.9728 16.2461C59.7178 16.2461 61.5271 13.9169 61.5271 10.818C61.5271 7.69939 59.5805 5.39001 56.8159 5.39001C55.0513 5.39001 54.1886 6.35719 53.7768 6.89012H53.6004V5.64661H51.3063V20ZM56.4826 14.0551C54.8944 14.0551 53.5808 12.8708 53.5808 10.818C53.5808 9.06133 54.6984 7.58096 56.4434 7.58096C58.0708 7.58096 59.3453 8.86395 59.3453 10.818C59.3453 12.7326 58.11 14.0551 56.4826 14.0551Z" fill="#2D2D31" />
|
||||
<path d="M64.5855 16.2296H67.8599L69.7226 8.11721H69.8402L71.7029 16.2296H74.9577L77.564 5.88678H75.2322L73.3695 14.0189H73.193L71.3303 5.88678H68.252L66.3697 14.0189H66.1933L64.3502 5.88678H61.8797L64.5855 16.2296Z" fill="#2D2D31" />
|
||||
<path d="M78.7361 16.2296H81.0498V11.1174C81.0498 9.16334 81.9517 7.9593 83.6379 7.9593H84.6575V5.63019H83.8928C82.5791 5.63019 81.5791 6.53815 81.187 7.40663H81.0301V5.88678H78.7361V16.2296Z" fill="#2D2D31" />
|
||||
<path d="M96.1389 16.2296H97.9428V14.1571H96.1585C95.4527 14.1571 95.1586 13.8413 95.1586 13.111V7.93956H98.0604V5.88678H95.1586V2.98526H92.9626V5.88678H91.0411V7.93956H92.8253V13.1307C92.8253 15.3217 94.139 16.2296 96.1389 16.2296Z" fill="#2D2D31" />
|
||||
<path d="M104.15 16.2461C106.287 16.2461 108.169 15.1802 108.836 13.0287L106.718 12.5155C106.346 13.6603 105.268 14.2525 104.13 14.2525C102.444 14.2525 101.326 13.1472 101.307 11.4102H109.091V10.7588C109.091 7.67965 107.189 5.39001 104.052 5.39001C101.287 5.39001 98.9148 7.58096 98.9148 10.8378C98.9148 13.9959 101.013 16.2461 104.15 16.2461ZM101.326 9.71269C101.464 8.46918 102.581 7.42305 104.052 7.42305C105.464 7.42305 106.62 8.31128 106.738 9.71269H101.326Z" fill="#2D2D31" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.0123 16.2296H87.6987V7.93956H85.8948V5.88678H90.0123V16.2296Z" fill="#2D2D31" />
|
||||
<path d="M88.6835 4.45145C89.5266 4.45145 90.154 3.81983 90.154 2.99082C90.154 2.18155 89.5266 1.54993 88.6835 1.54993C87.8404 1.54993 87.213 2.18155 87.213 2.99082C87.213 3.81983 87.8404 4.45145 88.6835 4.45145Z" fill="#2D2D31" />
|
||||
<path d="M20.2007 13.6935V18.258H8.88588C5.5894 18.258 2.71111 16.4222 1.17116 13.6935C0.947288 13.2968 0.751353 12.8806 0.586995 12.4486C0.26435 11.6021 0.0615332 10.6938 0 9.74603V8.51195C0.0133592 8.30074 0.03441 8.09119 0.0619381 7.88413C0.118209 7.45921 0.203222 7.04343 0.314953 6.63926C1.37195 2.80758 4.8089 0 8.88588 0C12.9629 0 16.3994 2.80758 17.4564 6.63926H12.6184C11.8241 5.39025 10.4493 4.5645 8.88588 4.5645C7.32245 4.5645 5.94767 5.39025 5.15341 6.63926C4.91132 7.01895 4.72349 7.43764 4.60042 7.88413C4.49112 8.27999 4.43282 8.69744 4.43282 9.12899C4.43282 10.4373 4.96962 11.6166 5.83027 12.4486C6.62778 13.2209 7.70299 13.6935 8.88588 13.6935H20.2007Z" fill="#FD366E" />
|
||||
<path d="M20.2007 7.88412V12.4486H11.9415C12.8022 11.6166 13.339 10.4373 13.339 9.12899C13.339 8.69744 13.2807 8.27999 13.1714 7.88412H20.2007Z" fill="#FD366E" />
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -864,7 +864,7 @@ $image = $this->getParam('image', '');
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
stop_signal: SIGINT
|
||||
image: openruntimes/executor:0.7.20
|
||||
image: openruntimes/executor:0.7.14
|
||||
networks:
|
||||
- appwrite
|
||||
- runtimes
|
||||
|
||||
+28
-39
@@ -18,9 +18,7 @@ use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Platform\Appwrite;
|
||||
use Executor\Executor;
|
||||
use Swoole\Process;
|
||||
use Swoole\Runtime;
|
||||
use Swoole\Timer;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\Cache\Adapter\Pool as CachePool;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
@@ -42,9 +40,7 @@ use Utopia\Queue\Message;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Queue\Server;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\Storage\Device\Telemetry as TelemetryDevice;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Telemetry\Adapter as Telemetry;
|
||||
use Utopia\Telemetry\Adapter\None as NoTelemetry;
|
||||
|
||||
Authorization::disable();
|
||||
@@ -94,13 +90,13 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register,
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
@@ -131,13 +127,13 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
return $database;
|
||||
@@ -153,13 +149,13 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setTenant($project->getSequence())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
@@ -172,7 +168,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database = null;
|
||||
return function (?Document $project = null) use ($pools, $cache, $database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
$database->setTenant($project->getSequence());
|
||||
return $database;
|
||||
}
|
||||
|
||||
@@ -187,7 +183,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
|
||||
// set tenant
|
||||
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
$database->setTenant($project->getSequence());
|
||||
}
|
||||
|
||||
return $database;
|
||||
@@ -315,29 +311,29 @@ Server::setResource('pools', function (Registry $register) {
|
||||
|
||||
Server::setResource('telemetry', fn () => new NoTelemetry());
|
||||
|
||||
Server::setResource('deviceForSites', function (Document $project, Telemetry $telemetry) {
|
||||
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_SITES . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
Server::setResource('deviceForSites', function (Document $project) {
|
||||
return getDevice(APP_STORAGE_SITES . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource('deviceForImports', function (Document $project, Telemetry $telemetry) {
|
||||
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_IMPORTS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
Server::setResource('deviceForImports', function (Document $project) {
|
||||
return getDevice(APP_STORAGE_IMPORTS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource('deviceForFunctions', function (Document $project, Telemetry $telemetry) {
|
||||
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
Server::setResource('deviceForFunctions', function (Document $project) {
|
||||
return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource('deviceForFiles', function (Document $project, Telemetry $telemetry) {
|
||||
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
Server::setResource('deviceForFiles', function (Document $project) {
|
||||
return getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource('deviceForBuilds', function (Document $project, Telemetry $telemetry) {
|
||||
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
Server::setResource('deviceForBuilds', function (Document $project) {
|
||||
return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource('deviceForCache', function (Document $project, Telemetry $telemetry) {
|
||||
return new TelemetryDevice($telemetry, getDevice(APP_STORAGE_CACHE . '/app-' . $project->getId()));
|
||||
}, ['project', 'telemetry']);
|
||||
Server::setResource('deviceForCache', function (Document $project) {
|
||||
return getDevice(APP_STORAGE_CACHE . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource(
|
||||
'isResourceBlocked',
|
||||
@@ -484,15 +480,8 @@ $worker
|
||||
});
|
||||
|
||||
$worker->workerStart()
|
||||
->action(function () use ($worker, $workerName) {
|
||||
Console::info("Worker $workerName started");
|
||||
|
||||
Process::signal(SIGTERM, function () use ($worker, $workerName) {
|
||||
Console::info("Stopping worker $workerName.");
|
||||
|
||||
$worker->stop();
|
||||
Timer::clearAll();
|
||||
});
|
||||
->action(function () use ($workerName) {
|
||||
Console::info("Worker $workerName started");
|
||||
});
|
||||
|
||||
$worker->start();
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php doctor $@
|
||||
php /usr/src/code/app/cli.php doctor $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php install $@
|
||||
php /usr/src/code/app/cli.php install $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php maintenance $@
|
||||
php /usr/src/code/app/cli.php maintenance $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php migrate $@
|
||||
php /usr/src/code/app/cli.php migrate $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php queue-count --type=failed $@
|
||||
php /usr/src/code/app/cli.php queue-count --type=failed $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php queue-count --type=processing $@
|
||||
php /usr/src/code/app/cli.php queue-count --type=processing $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php queue-count --type=success $@
|
||||
php /usr/src/code/app/cli.php queue-count --type=success $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php queue-retry $@
|
||||
php /usr/src/code/app/cli.php queue-retry $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/realtime.php $@
|
||||
php /usr/src/code/app/realtime.php $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php schedule-executions $@
|
||||
php /usr/src/code/app/cli.php schedule-executions $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php schedule-functions $@
|
||||
php /usr/src/code/app/cli.php schedule-functions $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php schedule-messages $@
|
||||
php /usr/src/code/app/cli.php schedule-messages $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php screenshot $@
|
||||
php /usr/src/code/app/cli.php screenshot $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php sdks $@
|
||||
php /usr/src/code/app/cli.php sdks $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php specs $@
|
||||
php /usr/src/code/app/cli.php specs $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php ssl $@
|
||||
php /usr/src/code/app/cli.php ssl $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php stats-resources $@
|
||||
php /usr/src/code/app/cli.php stats-resources $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec /usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml $@
|
||||
/usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php upgrade $@
|
||||
php /usr/src/code/app/cli.php upgrade $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php vars $@
|
||||
php /usr/src/code/app/cli.php vars $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php audits $@
|
||||
php /usr/src/code/app/worker.php audits $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php builds $@
|
||||
php /usr/src/code/app/worker.php builds $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php certificates $@
|
||||
php /usr/src/code/app/worker.php certificates $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php databases $@
|
||||
php /usr/src/code/app/worker.php databases $@
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php deletes $@
|
||||
php /usr/src/code/app/worker.php deletes $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php functions $@
|
||||
php /usr/src/code/app/worker.php functions $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php mails $@
|
||||
php /usr/src/code/app/worker.php mails $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php messaging $@
|
||||
php /usr/src/code/app/worker.php messaging $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php migrations $@
|
||||
php /usr/src/code/app/worker.php migrations $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php stats-resources $@
|
||||
php /usr/src/code/app/worker.php stats-resources $@
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php stats-usage $@
|
||||
php /usr/src/code/app/worker.php stats-usage $@
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/worker.php webhooks $@
|
||||
php /usr/src/code/app/worker.php webhooks $@
|
||||
+9
-9
@@ -53,7 +53,7 @@
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/detector": "0.1.*",
|
||||
"utopia-php/database": "0.69.*",
|
||||
"utopia-php/database": "0.71.*",
|
||||
"utopia-php/domains": "0.8.0",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
@@ -61,13 +61,13 @@
|
||||
"utopia-php/image": "0.8.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
"utopia-php/messaging": "0.18.*",
|
||||
"utopia-php/migration": "0.9.*",
|
||||
"utopia-php/messaging": "0.17.*",
|
||||
"utopia-php/migration": "0.10.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.11.*",
|
||||
"utopia-php/queue": "0.10.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
"utopia-php/storage": "0.18.*",
|
||||
"utopia-php/swoole": "0.8.*",
|
||||
@@ -76,17 +76,17 @@
|
||||
"utopia-php/vcs": "0.10.*",
|
||||
"utopia-php/websocket": "0.3.*",
|
||||
"matomo/device-detector": "6.1.*",
|
||||
"dragonmantank/cron-expression": "3.3.*",
|
||||
"phpmailer/phpmailer": "6.9.*",
|
||||
"chillerlan/php-qrcode": "4.3.*",
|
||||
"adhocore/jwt": "1.1.*",
|
||||
"dragonmantank/cron-expression": "3.3.2",
|
||||
"phpmailer/phpmailer": "6.9.1",
|
||||
"chillerlan/php-qrcode": "4.3.4",
|
||||
"adhocore/jwt": "1.1.2",
|
||||
"spomky-labs/otphp": "^10.0",
|
||||
"webonyx/graphql-php": "14.11.*",
|
||||
"league/csv": "9.14.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-fileinfo": "*",
|
||||
"appwrite/sdk-generator": "0.41.*",
|
||||
"appwrite/sdk-generator": "0.40.*",
|
||||
"phpunit/phpunit": "9.*",
|
||||
"swoole/ide-helper": "5.1.2",
|
||||
"phpstan/phpstan": "1.8.*",
|
||||
|
||||
Generated
+188
-180
@@ -4,27 +4,27 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "3230eea9e592f0b712e78c1ef5f5e244",
|
||||
"content-hash": "5027a541e6377eb2c87357b69f11daea",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/adhocore/php-jwt.git",
|
||||
"reference": "ad417603d9d45578b6af2089ad5b78f101c82367"
|
||||
"reference": "6c434af7170090bb7a8880d2bc220a2254ba7899"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/adhocore/php-jwt/zipball/ad417603d9d45578b6af2089ad5b78f101c82367",
|
||||
"reference": "ad417603d9d45578b6af2089ad5b78f101c82367",
|
||||
"url": "https://api.github.com/repos/adhocore/php-jwt/zipball/6c434af7170090bb7a8880d2bc220a2254ba7899",
|
||||
"reference": "6c434af7170090bb7a8880d2bc220a2254ba7899",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8.5"
|
||||
"phpunit/phpunit": "^6.5 || ^7.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -53,19 +53,15 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/adhocore/php-jwt/issues",
|
||||
"source": "https://github.com/adhocore/php-jwt/tree/1.1.3"
|
||||
"source": "https://github.com/adhocore/php-jwt/tree/1.1.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://paypal.me/ji10",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/adhocore",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-18T01:00:50+00:00"
|
||||
"time": "2021-02-20T09:56:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "appwrite/appwrite",
|
||||
@@ -161,16 +157,16 @@
|
||||
},
|
||||
{
|
||||
"name": "appwrite/php-runtimes",
|
||||
"version": "0.19.1",
|
||||
"version": "0.19.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/runtimes.git",
|
||||
"reference": "7bd0cc3cb97de625d7b07230bd91b121f88e72ae"
|
||||
"reference": "8d21483efc19b9d977e323188989ee67a188464b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/7bd0cc3cb97de625d7b07230bd91b121f88e72ae",
|
||||
"reference": "7bd0cc3cb97de625d7b07230bd91b121f88e72ae",
|
||||
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/8d21483efc19b9d977e323188989ee67a188464b",
|
||||
"reference": "8d21483efc19b9d977e323188989ee67a188464b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -210,9 +206,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/runtimes/issues",
|
||||
"source": "https://github.com/appwrite/runtimes/tree/0.19.1"
|
||||
"source": "https://github.com/appwrite/runtimes/tree/0.19.0"
|
||||
},
|
||||
"time": "2025-05-27T07:12:56+00:00"
|
||||
"time": "2025-03-25T22:37:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beberlei/assert",
|
||||
@@ -283,16 +279,16 @@
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.13.1",
|
||||
"version": "0.12.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brick/math.git",
|
||||
"reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04"
|
||||
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04",
|
||||
"reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba",
|
||||
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -331,7 +327,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/brick/math/issues",
|
||||
"source": "https://github.com/brick/math/tree/0.13.1"
|
||||
"source": "https://github.com/brick/math/tree/0.12.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -339,7 +335,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-29T13:50:30+00:00"
|
||||
"time": "2025-02-28T13:11:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
@@ -569,16 +565,16 @@
|
||||
},
|
||||
{
|
||||
"name": "dragonmantank/cron-expression",
|
||||
"version": "v3.3.3",
|
||||
"version": "v3.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dragonmantank/cron-expression.git",
|
||||
"reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a"
|
||||
"reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
|
||||
"reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a",
|
||||
"url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/782ca5968ab8b954773518e9e49a6f892a34b2a8",
|
||||
"reference": "782ca5968ab8b954773518e9e49a6f892a34b2a8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -618,7 +614,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/dragonmantank/cron-expression/issues",
|
||||
"source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3"
|
||||
"source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -626,7 +622,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-10T19:36:49+00:00"
|
||||
"time": "2022-09-10T18:51:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "giggsey/libphonenumber-for-php-lite",
|
||||
@@ -713,16 +709,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v4.31.1",
|
||||
"version": "v4.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "2b028ce8876254e2acbeceea7d9b573faad41864"
|
||||
"reference": "d59e31ce4bf0e4b48728e90c4d880839edb5be07"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/2b028ce8876254e2acbeceea7d9b573faad41864",
|
||||
"reference": "2b028ce8876254e2acbeceea7d9b573faad41864",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/d59e31ce4bf0e4b48728e90c4d880839edb5be07",
|
||||
"reference": "d59e31ce4bf0e4b48728e90c4d880839edb5be07",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -751,9 +747,9 @@
|
||||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.31.1"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.31.0"
|
||||
},
|
||||
"time": "2025-05-28T18:52:35+00:00"
|
||||
"time": "2025-05-14T16:17:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
@@ -2323,20 +2319,20 @@
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
"version": "4.8.1",
|
||||
"version": "4.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/uuid.git",
|
||||
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28"
|
||||
"reference": "91039bc1faa45ba123c4328958e620d382ec7088"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
|
||||
"reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
|
||||
"url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088",
|
||||
"reference": "91039bc1faa45ba123c4328958e620d382ec7088",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13",
|
||||
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12",
|
||||
"ext-json": "*",
|
||||
"php": "^8.0",
|
||||
"ramsey/collection": "^1.2 || ^2.0"
|
||||
@@ -2345,23 +2341,26 @@
|
||||
"rhumsaa/uuid": "self.version"
|
||||
},
|
||||
"require-dev": {
|
||||
"captainhook/captainhook": "^5.25",
|
||||
"captainhook/captainhook": "^5.10",
|
||||
"captainhook/plugin-composer": "^5.3",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||
"ergebnis/composer-normalize": "^2.47",
|
||||
"mockery/mockery": "^1.6",
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
|
||||
"doctrine/annotations": "^1.8",
|
||||
"ergebnis/composer-normalize": "^2.15",
|
||||
"mockery/mockery": "^1.3",
|
||||
"paragonie/random-lib": "^2",
|
||||
"php-mock/php-mock": "^2.6",
|
||||
"php-mock/php-mock-mockery": "^1.5",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.4.0",
|
||||
"phpbench/phpbench": "^1.2.14",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"phpstan/phpstan-mockery": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"slevomat/coding-standard": "^8.18",
|
||||
"squizlabs/php_codesniffer": "^3.13"
|
||||
"php-mock/php-mock": "^2.2",
|
||||
"php-mock/php-mock-mockery": "^1.3",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.1",
|
||||
"phpbench/phpbench": "^1.0",
|
||||
"phpstan/extension-installer": "^1.1",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpstan/phpstan-mockery": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.1",
|
||||
"phpunit/phpunit": "^8.5 || ^9",
|
||||
"ramsey/composer-repl": "^1.4",
|
||||
"slevomat/coding-standard": "^8.4",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"vimeo/psalm": "^4.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
|
||||
@@ -2396,9 +2395,19 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/uuid/issues",
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.8.1"
|
||||
"source": "https://github.com/ramsey/uuid/tree/4.7.6"
|
||||
},
|
||||
"time": "2025-06-01T06:28:46+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/ramsey",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-27T21:32:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spomky-labs/otphp",
|
||||
@@ -2477,16 +2486,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.6.0",
|
||||
"version": "v3.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"
|
||||
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62",
|
||||
"reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
|
||||
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2499,7 +2508,7 @@
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.6-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2524,7 +2533,7 @@
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0"
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2540,20 +2549,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-25T14:21:43+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client.git",
|
||||
"reference": "57e4fb86314015a695a750ace358d07a7e37b8a9"
|
||||
"reference": "78981a2ffef6437ed92d4d7e2a86a82f256c6dc6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/57e4fb86314015a695a750ace358d07a7e37b8a9",
|
||||
"reference": "57e4fb86314015a695a750ace358d07a7e37b8a9",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/78981a2ffef6437ed92d4d7e2a86a82f256c6dc6",
|
||||
"reference": "78981a2ffef6437ed92d4d7e2a86a82f256c6dc6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2619,7 +2628,7 @@
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.2.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2635,20 +2644,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-02T08:23:16+00:00"
|
||||
"time": "2025-02-13T10:27:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client-contracts",
|
||||
"version": "v3.6.0",
|
||||
"version": "v3.5.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client-contracts.git",
|
||||
"reference": "75d7043853a42837e68111812f4d964b01e5101c"
|
||||
"reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/75d7043853a42837e68111812f4d964b01e5101c",
|
||||
"reference": "75d7043853a42837e68111812f4d964b01e5101c",
|
||||
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645",
|
||||
"reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2661,7 +2670,7 @@
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.6-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2697,7 +2706,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client-contracts/tree/v3.6.0"
|
||||
"source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2713,7 +2722,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-29T11:18:49+00:00"
|
||||
"time": "2024-12-07T08:49:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
@@ -2874,16 +2883,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v3.6.0",
|
||||
"version": "v3.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4"
|
||||
"reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
|
||||
"reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0",
|
||||
"reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2901,7 +2910,7 @@
|
||||
"name": "symfony/contracts"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "3.6-dev"
|
||||
"dev-main": "3.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -2937,7 +2946,7 @@
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.6.0"
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2953,7 +2962,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-25T09:37:31+00:00"
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tbachert/spi",
|
||||
@@ -3490,16 +3499,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.69.7",
|
||||
"version": "0.71.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "3db51ec544b3f287511209e34bab3f5ec85fa56e"
|
||||
"reference": "cf463c0a5c64a4168fe56266ace4ae835d61c920"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/3db51ec544b3f287511209e34bab3f5ec85fa56e",
|
||||
"reference": "3db51ec544b3f287511209e34bab3f5ec85fa56e",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/cf463c0a5c64a4168fe56266ace4ae835d61c920",
|
||||
"reference": "cf463c0a5c64a4168fe56266ace4ae835d61c920",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3540,9 +3549,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.69.7"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.71.0"
|
||||
},
|
||||
"time": "2025-05-30T14:41:25+00:00"
|
||||
"time": "2025-05-23T07:32:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
@@ -3785,16 +3794,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.8.4",
|
||||
"version": "0.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "ce788ff0121a79286fdbe3ef3eba566de646df65"
|
||||
"reference": "8820b0e53b3636b7bdf815e92394d333fef06f26"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/ce788ff0121a79286fdbe3ef3eba566de646df65",
|
||||
"reference": "ce788ff0121a79286fdbe3ef3eba566de646df65",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/8820b0e53b3636b7bdf815e92394d333fef06f26",
|
||||
"reference": "8820b0e53b3636b7bdf815e92394d333fef06f26",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3828,9 +3837,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.8.4"
|
||||
"source": "https://github.com/utopia-php/image/tree/0.8.3"
|
||||
},
|
||||
"time": "2025-06-03T08:32:20+00:00"
|
||||
"time": "2025-05-15T10:39:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
@@ -3939,16 +3948,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.18.0",
|
||||
"version": "0.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "c151aa5d4d475c788ca15c210b5b2017e21c41d6"
|
||||
"reference": "c51915d0e030db3a3add37f1561751d18b2d9a85"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/c151aa5d4d475c788ca15c210b5b2017e21c41d6",
|
||||
"reference": "c151aa5d4d475c788ca15c210b5b2017e21c41d6",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/c51915d0e030db3a3add37f1561751d18b2d9a85",
|
||||
"reference": "c51915d0e030db3a3add37f1561751d18b2d9a85",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3984,22 +3993,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.18.0"
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.17.0"
|
||||
},
|
||||
"time": "2025-05-15T05:00:03+00:00"
|
||||
"time": "2025-05-12T16:14:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.9.3",
|
||||
"version": "0.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "e518d39eb550fde36bc5cf06c9bd7b2faf5dbedd"
|
||||
"reference": "0b0e94c4b5243c5566b9634b07ba2ec5f7990914"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/e518d39eb550fde36bc5cf06c9bd7b2faf5dbedd",
|
||||
"reference": "e518d39eb550fde36bc5cf06c9bd7b2faf5dbedd",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/0b0e94c4b5243c5566b9634b07ba2ec5f7990914",
|
||||
"reference": "0b0e94c4b5243c5566b9634b07ba2ec5f7990914",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4040,9 +4049,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.9.3"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.10.0"
|
||||
},
|
||||
"time": "2025-05-01T05:41:26+00:00"
|
||||
"time": "2025-05-23T07:40:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/orchestration",
|
||||
@@ -4096,16 +4105,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/platform",
|
||||
"version": "0.7.8",
|
||||
"version": "0.7.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/platform.git",
|
||||
"reference": "e3a4536c46f10988b1a446ec6b8dd8a9914be854"
|
||||
"reference": "8c43cd866148a7c4c495e3401268429e338004b3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/e3a4536c46f10988b1a446ec6b8dd8a9914be854",
|
||||
"reference": "e3a4536c46f10988b1a446ec6b8dd8a9914be854",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/8c43cd866148a7c4c495e3401268429e338004b3",
|
||||
"reference": "8c43cd866148a7c4c495e3401268429e338004b3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4114,7 +4123,7 @@
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/queue": "0.11.*"
|
||||
"utopia-php/queue": "0.10.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
@@ -4140,9 +4149,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/platform/issues",
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.8"
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.7"
|
||||
},
|
||||
"time": "2025-05-30T10:05:43+00:00"
|
||||
"time": "2025-05-20T09:23:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
@@ -4251,16 +4260,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/queue",
|
||||
"version": "0.11.1",
|
||||
"version": "0.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/queue.git",
|
||||
"reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6"
|
||||
"reference": "0eccc559168ea72241c39a4c482d868314666be1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/498bbbef418b1db71b51e1bb62f5d1d752ddd8d6",
|
||||
"reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/0eccc559168ea72241c39a4c482d868314666be1",
|
||||
"reference": "0eccc559168ea72241c39a4c482d868314666be1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4311,9 +4320,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/queue/issues",
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.11.1"
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.10.0"
|
||||
},
|
||||
"time": "2025-05-30T11:50:34+00:00"
|
||||
"time": "2025-04-17T12:15:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
@@ -4369,16 +4378,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.18.13",
|
||||
"version": "0.18.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "3d8ce53ae042173bf230445e996056c5f65ded22"
|
||||
"reference": "9a2556c39b5f4d9f8e79111fd34ec889b7bb1e97"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/3d8ce53ae042173bf230445e996056c5f65ded22",
|
||||
"reference": "3d8ce53ae042173bf230445e996056c5f65ded22",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/9a2556c39b5f4d9f8e79111fd34ec889b7bb1e97",
|
||||
"reference": "9a2556c39b5f4d9f8e79111fd34ec889b7bb1e97",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4421,9 +4430,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.18.13"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.18.12"
|
||||
},
|
||||
"time": "2025-05-26T13:10:35+00:00"
|
||||
"time": "2025-05-15T07:55:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
@@ -4584,16 +4593,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/vcs",
|
||||
"version": "0.10.4",
|
||||
"version": "0.10.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/vcs.git",
|
||||
"reference": "f635b368909eb3c3fe57344fe43525e74e8fdc03"
|
||||
"reference": "1f9823ebcb8fd098607de0074f18f48e28985012"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/f635b368909eb3c3fe57344fe43525e74e8fdc03",
|
||||
"reference": "f635b368909eb3c3fe57344fe43525e74e8fdc03",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/1f9823ebcb8fd098607de0074f18f48e28985012",
|
||||
"reference": "1f9823ebcb8fd098607de0074f18f48e28985012",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4627,9 +4636,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/vcs/issues",
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.10.4"
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.10.2"
|
||||
},
|
||||
"time": "2025-06-02T09:18:36+00:00"
|
||||
"time": "2025-04-17T04:35:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
@@ -4807,16 +4816,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.41.1",
|
||||
"version": "0.40.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "6d9318abf4542a757c87abf056557d6afa1dc06b"
|
||||
"reference": "05b53cf30c59fe5934d57207fefbc8ae8feb5dbf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6d9318abf4542a757c87abf056557d6afa1dc06b",
|
||||
"reference": "6d9318abf4542a757c87abf056557d6afa1dc06b",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/05b53cf30c59fe5934d57207fefbc8ae8feb5dbf",
|
||||
"reference": "05b53cf30c59fe5934d57207fefbc8ae8feb5dbf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4852,9 +4861,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.1"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.19"
|
||||
},
|
||||
"time": "2025-06-01T04:20:04+00:00"
|
||||
"time": "2025-05-24T22:49:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -5331,16 +5340,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v5.5.0",
|
||||
"version": "v5.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9"
|
||||
"reference": "447a020a1f875a434d62f2a401f53b82a396e494"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9",
|
||||
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494",
|
||||
"reference": "447a020a1f875a434d62f2a401f53b82a396e494",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5383,9 +5392,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0"
|
||||
},
|
||||
"time": "2025-05-31T08:24:38+00:00"
|
||||
"time": "2024-12-30T11:07:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@@ -7253,24 +7262,23 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44"
|
||||
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44",
|
||||
"reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
|
||||
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/string": "^7.2"
|
||||
"symfony/string": "^6.4|^7.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<6.4",
|
||||
@@ -7327,7 +7335,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7343,11 +7351,11 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-05-24T10:34:04+00:00"
|
||||
"time": "2025-04-07T19:09:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
@@ -7393,7 +7401,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7413,16 +7421,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
|
||||
"reference": "87a71856f2f56e4100373e92529eed3171695cfb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
|
||||
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb",
|
||||
"reference": "87a71856f2f56e4100373e92529eed3171695cfb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7457,7 +7465,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/finder/tree/v7.2.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7473,20 +7481,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-30T19:00:26+00:00"
|
||||
"time": "2024-12-30T19:00:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca"
|
||||
"reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca",
|
||||
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50",
|
||||
"reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7524,7 +7532,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7540,7 +7548,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-04T13:12:05+00:00"
|
||||
"time": "2024-11-20T11:17:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
@@ -7858,16 +7866,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
|
||||
"reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7899,7 +7907,7 @@
|
||||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -7915,20 +7923,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-17T09:11:12+00:00"
|
||||
"time": "2025-03-13T12:21:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.2.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
|
||||
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
|
||||
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -7986,7 +7994,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/string/tree/v7.2.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8002,7 +8010,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-20T20:19:01+00:00"
|
||||
"time": "2025-04-20T20:18:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
|
||||
+2
-2
@@ -213,7 +213,7 @@ services:
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: appwrite/console:6.0.32
|
||||
image: appwrite/console:6.0.13
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
@@ -951,7 +951,7 @@ services:
|
||||
hostname: exc1
|
||||
<<: *x-logging
|
||||
stop_signal: SIGINT
|
||||
image: openruntimes/executor:0.7.20
|
||||
image: openruntimes/executor:0.7.16
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
appwrite databases upsertDocument \
|
||||
--databaseId <DATABASE_ID> \
|
||||
--collectionId <COLLECTION_ID> \
|
||||
--documentId <DOCUMENT_ID> \
|
||||
--data '{ "key": "value" }' \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
appwrite databases upsertDocuments \
|
||||
--databaseId <DATABASE_ID> \
|
||||
--collectionId <COLLECTION_ID> \
|
||||
--documents one two three
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class Targets
|
||||
$database->deleteDocuments(
|
||||
'subscribers',
|
||||
[
|
||||
Query::equal('targetInternalId', [$target->getInternalId()]),
|
||||
Query::equal('targetInternalId', [$target->getSequence()]),
|
||||
Query::orderAsc(),
|
||||
],
|
||||
Database::DELETE_BATCH_SIZE,
|
||||
@@ -35,7 +35,7 @@ class Targets
|
||||
$topicId = $subscriber->getAttribute('topicId');
|
||||
$topicInternalId = $subscriber->getAttribute('topicInternalId');
|
||||
$topic = $database->getDocument('topics', $topicId);
|
||||
if (!$topic->isEmpty() && $topic->getInternalId() === $topicInternalId) {
|
||||
if (!$topic->isEmpty() && $topic->getSequence() === $topicInternalId) {
|
||||
$totalAttribute = match ($target->getAttribute('providerType')) {
|
||||
MESSAGE_TYPE_EMAIL => 'emailTotal',
|
||||
MESSAGE_TYPE_SMS => 'smsTotal',
|
||||
|
||||
@@ -320,7 +320,7 @@ class Event
|
||||
if ($this->project) {
|
||||
$trimmed['project'] = new Document([
|
||||
'$id' => $this->project->getId(),
|
||||
'$internalId' => $this->project->getInternalId(),
|
||||
'$sequence' => $this->project->getSequence(),
|
||||
'database' => $this->project->getAttribute('database')
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -124,8 +124,6 @@ class Exception extends \Exception
|
||||
/** Membership */
|
||||
public const MEMBERSHIP_NOT_FOUND = 'membership_not_found';
|
||||
public const MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed';
|
||||
public const MEMBERSHIP_DELETION_PROHIBITED = 'membership_deletion_prohibited';
|
||||
public const MEMBERSHIP_DOWNGRADE_PROHIBITED = 'membership_downgrade_prohibited';
|
||||
|
||||
/** Avatars */
|
||||
public const AVATAR_SET_NOT_FOUND = 'avatar_set_not_found';
|
||||
|
||||
@@ -157,7 +157,7 @@ abstract class Migration
|
||||
*/
|
||||
public function forEachDocument(callable $callback): void
|
||||
{
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
$projectInternalId = $this->project->getSequence();
|
||||
|
||||
$collections = match ($projectInternalId) {
|
||||
'console' => $this->collections['console'],
|
||||
@@ -210,7 +210,7 @@ abstract class Migration
|
||||
{
|
||||
$name ??= $id;
|
||||
|
||||
$collectionType = match ($this->project->getInternalId()) {
|
||||
$collectionType = match ($this->project->getSequence()) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
@@ -261,7 +261,7 @@ abstract class Migration
|
||||
): void {
|
||||
$from ??= $collectionId;
|
||||
|
||||
$collectionType = match ($this->project->getInternalId()) {
|
||||
$collectionType = match ($this->project->getSequence()) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
@@ -326,7 +326,7 @@ abstract class Migration
|
||||
): void {
|
||||
$from ??= $collectionId;
|
||||
|
||||
$collectionType = match ($this->project->getInternalId()) {
|
||||
$collectionType = match ($this->project->getSequence()) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
@@ -384,7 +384,7 @@ abstract class Migration
|
||||
{
|
||||
$from ??= $collectionId;
|
||||
|
||||
$collectionType = match ($this->project->getInternalId()) {
|
||||
$collectionType = match ($this->project->getSequence()) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
@@ -430,7 +430,7 @@ abstract class Migration
|
||||
*/
|
||||
protected function changeAttributeInternalType(string $collection, string $attribute, string $type): void
|
||||
{
|
||||
$stmt = $this->pdo->prepare("ALTER TABLE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$collection}` MODIFY `$attribute` $type;");
|
||||
$stmt = $this->pdo->prepare("ALTER TABLE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$collection}` MODIFY `$attribute` $type;");
|
||||
|
||||
try {
|
||||
$stmt->execute();
|
||||
|
||||
@@ -95,7 +95,7 @@ class V15 extends Migration
|
||||
$this->migrateStatsMetric('storage.files.delete', 'files.$all.requests.delete');
|
||||
|
||||
foreach ($this->documentsIterator('buckets') as $bucket) {
|
||||
$bucketTable = "bucket_{$bucket->getInternalId()}";
|
||||
$bucketTable = "bucket_{$bucket->getSequence()}";
|
||||
|
||||
$this->createPermissionsColumn($bucketTable);
|
||||
$this->migrateDateTimeAttribute($bucketTable, '_createdAt');
|
||||
@@ -178,7 +178,7 @@ class V15 extends Migration
|
||||
* Migrate every Database.
|
||||
*/
|
||||
foreach ($this->documentsIterator('databases') as $database) {
|
||||
$databaseTable = "database_{$database->getInternalId()}";
|
||||
$databaseTable = "database_{$database->getSequence()}";
|
||||
$this->createPermissionsColumn($databaseTable);
|
||||
$this->migrateDateTimeAttribute($databaseTable, '_createdAt');
|
||||
$this->migrateDateTimeAttribute($databaseTable, '_updatedAt');
|
||||
@@ -216,7 +216,7 @@ class V15 extends Migration
|
||||
*/
|
||||
Console::info("Migrating Collections of {$database->getId()} ({$database->getAttribute('name')})");
|
||||
foreach ($this->documentsIterator($databaseTable) as $collection) {
|
||||
$collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}";
|
||||
$collectionTable = "{$databaseTable}_collection_{$collection->getSequence()}";
|
||||
$this->createPermissionsColumn($collectionTable);
|
||||
$this->migrateDateTimeAttribute($collectionTable, '_createdAt');
|
||||
$this->migrateDateTimeAttribute($collectionTable, '_updatedAt');
|
||||
@@ -277,7 +277,7 @@ class V15 extends Migration
|
||||
$this->removeWritePermissions($databaseTable);
|
||||
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute("database_{$database->getInternalId()}", 'permission');
|
||||
$this->dbForProject->deleteAttribute("database_{$database->getSequence()}", 'permission');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'permission' from {$databaseTable}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -293,7 +293,7 @@ class V15 extends Migration
|
||||
protected function removeWritePermissions(string $table): void
|
||||
{
|
||||
try {
|
||||
$this->pdo->prepare("DELETE FROM `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}_perms` WHERE _type = 'write'")->execute();
|
||||
$this->pdo->prepare("DELETE FROM `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$table}_perms` WHERE _type = 'write'")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Remove 'write' permissions from {$table}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -309,7 +309,7 @@ class V15 extends Migration
|
||||
*/
|
||||
protected function getSQLColumnTypes(string $table): array
|
||||
{
|
||||
$query = $this->pdo->prepare("SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '_{$this->project->getInternalId()}_{$table}' AND table_schema = '{$this->dbForProject->getDatabase()}'");
|
||||
$query = $this->pdo->prepare("SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '_{$this->project->getSequence()}_{$table}' AND table_schema = '{$this->dbForProject->getDatabase()}'");
|
||||
$query->execute();
|
||||
|
||||
return array_reduce($query->fetchAll(), function (array $carry, array $item) {
|
||||
@@ -331,8 +331,8 @@ class V15 extends Migration
|
||||
|
||||
if ($columns[$attribute] === 'int') {
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` MODIFY {$attribute} VARCHAR(64)")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` SET {$attribute} = IF({$attribute} = 0, NULL, FROM_UNIXTIME({$attribute}))")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$table}` MODIFY {$attribute} VARCHAR(64)")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$table}` SET {$attribute} = IF({$attribute} = 0, NULL, FROM_UNIXTIME({$attribute}))")->execute();
|
||||
$columns[$attribute] = 'varchar';
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
@@ -341,7 +341,7 @@ class V15 extends Migration
|
||||
|
||||
if ($columns[$attribute] === 'varchar') {
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` MODIFY {$attribute} DATETIME(3)")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$table}` MODIFY {$attribute} DATETIME(3)")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
@@ -387,7 +387,7 @@ class V15 extends Migration
|
||||
|
||||
if (!array_key_exists('_permissions', $columns)) {
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` ADD `_permissions` MEDIUMTEXT DEFAULT NULL")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$table}` ADD `_permissions` MEDIUMTEXT DEFAULT NULL")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Add '_permissions' column to '{$table}': {$th->getMessage()}");
|
||||
}
|
||||
@@ -408,7 +408,7 @@ class V15 extends Migration
|
||||
{
|
||||
$table ??= $document->getCollection();
|
||||
|
||||
$query = $this->pdo->prepare("SELECT * FROM `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}_perms` WHERE _document = '{$document->getId()}'");
|
||||
$query = $this->pdo->prepare("SELECT * FROM `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_{$table}_perms` WHERE _document = '{$document->getId()}'");
|
||||
$query->execute();
|
||||
$results = $query->fetchAll();
|
||||
$permissions = [];
|
||||
@@ -466,7 +466,7 @@ class V15 extends Migration
|
||||
|
||||
Console::log("Migrating Collection \"{$id}\"");
|
||||
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
|
||||
switch ($id) {
|
||||
case '_metadata':
|
||||
@@ -746,7 +746,7 @@ class V15 extends Migration
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'functionId' => $function->getId(),
|
||||
'functionInternalId' => $function->getInternalId(),
|
||||
'functionInternalId' => $function->getSequence(),
|
||||
'key' => (string) $key,
|
||||
'value' => (string) $value,
|
||||
'search' => implode(' ', [$variableId, $key, $function->getId()])
|
||||
@@ -1470,9 +1470,9 @@ class V15 extends Migration
|
||||
$from = $this->pdo->quote($from);
|
||||
$to = $this->pdo->quote($to);
|
||||
|
||||
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating steps from {$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_stats:" . $th->getMessage());
|
||||
Console::warning("Migrating steps from {$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_stats:" . $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class V16 extends Migration
|
||||
|
||||
Console::log("Migrating Collection \"{$id}\"");
|
||||
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
|
||||
switch ($id) {
|
||||
case 'sessions':
|
||||
|
||||
@@ -44,7 +44,7 @@ class V17 extends Migration
|
||||
protected function migrateBuckets(): void
|
||||
{
|
||||
foreach ($this->documentsIterator('buckets') as $bucket) {
|
||||
$id = "bucket_{$bucket->getInternalId()}";
|
||||
$id = "bucket_{$bucket->getSequence()}";
|
||||
|
||||
try {
|
||||
$this->dbForProject->updateAttribute($id, 'mimeType', Database::VAR_STRING, 255, true, false);
|
||||
@@ -67,7 +67,7 @@ class V17 extends Migration
|
||||
|
||||
Console::log("Migrating Collection \"{$id}\"");
|
||||
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
|
||||
switch ($id) {
|
||||
case 'builds':
|
||||
|
||||
@@ -26,7 +26,7 @@ class V18 extends Migration
|
||||
}
|
||||
|
||||
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
$this->addDocumentSecurityToProject();
|
||||
|
||||
Console::info('Migrating Databases');
|
||||
@@ -48,12 +48,12 @@ class V18 extends Migration
|
||||
private function migrateDatabases(): void
|
||||
{
|
||||
foreach ($this->documentsIterator('databases') as $database) {
|
||||
$databaseTable = "database_{$database->getInternalId()}";
|
||||
$databaseTable = "database_{$database->getSequence()}";
|
||||
|
||||
Console::info("Migrating Collections of {$database->getId()} ({$database->getAttribute('name')})");
|
||||
|
||||
foreach ($this->documentsIterator($databaseTable) as $collection) {
|
||||
$collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}";
|
||||
$collectionTable = "{$databaseTable}_collection_{$collection->getSequence()}";
|
||||
|
||||
foreach ($collection['attributes'] ?? [] as $attribute) {
|
||||
if ($attribute['type'] !== Database::VAR_FLOAT) {
|
||||
@@ -197,7 +197,7 @@ class V18 extends Migration
|
||||
* Set the bucket permission in the metadata table
|
||||
*/
|
||||
try {
|
||||
$internalBucketId = "bucket_{$this->project->getInternalId()}";
|
||||
$internalBucketId = "bucket_{$this->project->getSequence()}";
|
||||
$permissions = $document->getPermissions();
|
||||
$fileSecurity = $document->getAttribute('fileSecurity', false);
|
||||
$this->dbForProject->updateCollection($internalBucketId, $permissions, $fileSecurity);
|
||||
@@ -224,8 +224,8 @@ class V18 extends Migration
|
||||
// Nonetheless, there's nothing else we can do here.
|
||||
break;
|
||||
}
|
||||
$internalId = $user->getInternalId();
|
||||
$document->setAttribute('userId', $internalId);
|
||||
$sequence = $user->getSequence();
|
||||
$document->setAttribute('userId', $sequence);
|
||||
$data = $document->getAttribute('data', []);
|
||||
$data['userId'] = $user->getId();
|
||||
$document->setAttribute('data', $data);
|
||||
@@ -244,7 +244,7 @@ class V18 extends Migration
|
||||
/**
|
||||
* Create 'documentSecurity' column
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}__metadata` ADD COLUMN IF NOT EXISTS documentSecurity TINYINT(1);")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}__metadata` ADD COLUMN IF NOT EXISTS documentSecurity TINYINT(1);")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
@@ -253,7 +253,7 @@ class V18 extends Migration
|
||||
/**
|
||||
* Set 'documentSecurity' column to 1 if NULL
|
||||
*/
|
||||
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}__metadata` SET documentSecurity = 1 WHERE documentSecurity IS NULL")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}__metadata` SET documentSecurity = 1 WHERE documentSecurity IS NULL")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class V19 extends Migration
|
||||
}
|
||||
|
||||
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCollections();
|
||||
@@ -100,7 +100,7 @@ class V19 extends Migration
|
||||
protected function migrateBuckets(): void
|
||||
{
|
||||
foreach ($this->documentsIterator('buckets') as $bucket) {
|
||||
$id = "bucket_{$bucket->getInternalId()}";
|
||||
$id = "bucket_{$bucket->getSequence()}";
|
||||
Console::log("Migrating Bucket {$id} {$bucket->getId()} ({$bucket->getAttribute('name')})");
|
||||
|
||||
try {
|
||||
@@ -121,7 +121,7 @@ class V19 extends Migration
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
$internalProjectId = $this->project->getSequence();
|
||||
$collectionType = match ($internalProjectId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
@@ -680,7 +680,7 @@ class V19 extends Migration
|
||||
case 'builds':
|
||||
$deploymentId = $document->getAttribute('deploymentId');
|
||||
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getSequence());
|
||||
|
||||
$stdout = $document->getAttribute('stdout', '');
|
||||
$stderr = $document->getAttribute('stderr', '');
|
||||
@@ -692,12 +692,12 @@ class V19 extends Migration
|
||||
case 'deployments':
|
||||
$resourceId = $document->getAttribute('resourceId');
|
||||
$function = $this->dbForProject->getDocument('functions', $resourceId);
|
||||
$document->setAttribute('resourceInternalId', $function->getInternalId());
|
||||
$document->setAttribute('resourceInternalId', $function->getSequence());
|
||||
|
||||
$buildId = $document->getAttribute('buildId');
|
||||
if (!empty($buildId)) {
|
||||
$build = $this->dbForProject->getDocument('builds', $buildId);
|
||||
$document->setAttribute('buildInternalId', $build->getInternalId());
|
||||
$document->setAttribute('buildInternalId', $build->getSequence());
|
||||
}
|
||||
|
||||
$commands = $this->getFunctionCommands($function);
|
||||
@@ -707,11 +707,11 @@ class V19 extends Migration
|
||||
case 'executions':
|
||||
$functionId = $document->getAttribute('functionId');
|
||||
$function = $this->dbForProject->getDocument('functions', $functionId);
|
||||
$document->setAttribute('functionInternalId', $function->getInternalId());
|
||||
$document->setAttribute('functionInternalId', $function->getSequence());
|
||||
|
||||
$deploymentId = $document->getAttribute('deploymentId');
|
||||
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getSequence());
|
||||
break;
|
||||
case 'functions':
|
||||
$document->setAttribute('live', $document->getAttribute('live', true));
|
||||
@@ -721,7 +721,7 @@ class V19 extends Migration
|
||||
|
||||
if (!empty($deploymentId)) {
|
||||
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getSequence());
|
||||
$document->setAttribute('entrypoint', $deployment->getAttribute('entrypoint'));
|
||||
}
|
||||
|
||||
@@ -733,7 +733,7 @@ class V19 extends Migration
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $document->getId(),
|
||||
'resourceInternalId' => $document->getInternalId(),
|
||||
'resourceInternalId' => $document->getSequence(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $this->project->getId(),
|
||||
'schedule' => $document->getAttribute('schedule'),
|
||||
@@ -741,7 +741,7 @@ class V19 extends Migration
|
||||
]));
|
||||
|
||||
$document->setAttribute('scheduleId', $schedule->getId());
|
||||
$document->setAttribute('scheduleInternalId', $schedule->getInternalId());
|
||||
$document->setAttribute('scheduleInternalId', $schedule->getSequence());
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -799,7 +799,7 @@ class V19 extends Migration
|
||||
*/
|
||||
public function forEachDocument(callable $callback): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
$internalProjectId = $this->project->getSequence();
|
||||
|
||||
$collections = match ($internalProjectId) {
|
||||
'console' => $this->collections['console'],
|
||||
|
||||
@@ -36,13 +36,13 @@ class V20 extends Migration
|
||||
}
|
||||
|
||||
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCollections();
|
||||
|
||||
// No need to migrate stats for console
|
||||
if ($this->project->getInternalId() !== 'console') {
|
||||
if ($this->project->getSequence() !== 'console') {
|
||||
$this->migrateUsageMetrics('project.$all.network.requests', 'network.requests');
|
||||
$this->migrateUsageMetrics('project.$all.network.outbound', 'network.outbound');
|
||||
$this->migrateUsageMetrics('project.$all.network.inbound', 'network.inbound');
|
||||
@@ -71,7 +71,7 @@ class V20 extends Migration
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
$internalProjectId = $this->project->getSequence();
|
||||
$collectionType = match ($internalProjectId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
@@ -510,7 +510,7 @@ class V20 extends Migration
|
||||
Console::log("Migrating Functions usage stats of {$function->getId()} ({$function->getAttribute('name')})");
|
||||
|
||||
$functionId = $function->getId();
|
||||
$functionInternalId = $function->getInternalId();
|
||||
$functionInternalId = $function->getSequence();
|
||||
|
||||
$this->migrateUsageMetrics("deployment.$functionId.storage.size", "function.$functionInternalId.deployments.storage");
|
||||
$this->migrateUsageMetrics("builds.$functionId.compute.total", "$functionInternalId.builds");
|
||||
@@ -536,22 +536,22 @@ class V20 extends Migration
|
||||
foreach ($this->documentsIterator('databases') as $database) {
|
||||
Console::log("Migrating Collections of {$database->getId()} ({$database->getAttribute('name')})");
|
||||
|
||||
$databaseTable = "database_{$database->getInternalId()}";
|
||||
$databaseTable = "database_{$database->getSequence()}";
|
||||
|
||||
// Database level
|
||||
$databaseId = $database->getId();
|
||||
$databaseInternalId = $database->getInternalId();
|
||||
$databaseInternalId = $database->getSequence();
|
||||
|
||||
$this->migrateUsageMetrics("collections.$databaseId.count.total", "$databaseInternalId.collections");
|
||||
$this->migrateUsageMetrics("documents.$databaseId.count.total", "$databaseInternalId.documents");
|
||||
|
||||
foreach ($this->documentsIterator($databaseTable) as $collection) {
|
||||
$collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}";
|
||||
$collectionTable = "{$databaseTable}_collection_{$collection->getSequence()}";
|
||||
Console::log("Migrating Collections of {$collectionTable} {$collection->getId()} ({$collection->getAttribute('name')})");
|
||||
|
||||
// Collection level
|
||||
$collectionId = $collection->getId();
|
||||
$collectionInternalId = $collection->getInternalId();
|
||||
$collectionInternalId = $collection->getSequence();
|
||||
|
||||
$this->migrateUsageMetrics("documents.$databaseId/$collectionId.count.total", "$databaseInternalId.$collectionInternalId.documents");
|
||||
}
|
||||
@@ -573,12 +573,12 @@ class V20 extends Migration
|
||||
$this->migrateUsageMetrics('files.$all.storage.size', 'files.storage');
|
||||
|
||||
foreach ($this->documentsIterator('buckets') as $bucket) {
|
||||
$id = "bucket_{$bucket->getInternalId()}";
|
||||
$id = "bucket_{$bucket->getSequence()}";
|
||||
Console::log("Migrating Bucket {$id} {$bucket->getId()} ({$bucket->getAttribute('name')})");
|
||||
|
||||
// Bucket level
|
||||
$bucketId = $bucket->getId();
|
||||
$bucketInternalId = $bucket->getInternalId();
|
||||
$bucketInternalId = $bucket->getSequence();
|
||||
|
||||
$this->migrateUsageMetrics("files.$bucketId.count.total", "$bucketInternalId.files");
|
||||
$this->migrateUsageMetrics("files.$bucketId.storage.size", "$bucketInternalId.files.storage");
|
||||
@@ -605,7 +605,7 @@ class V20 extends Migration
|
||||
$target = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $document->getId(),
|
||||
'userInternalId' => $document->getInternalId(),
|
||||
'userInternalId' => $document->getSequence(),
|
||||
'providerType' => MESSAGE_TYPE_EMAIL,
|
||||
'identifier' => $document->getAttribute('email'),
|
||||
]);
|
||||
@@ -620,7 +620,7 @@ class V20 extends Migration
|
||||
$target = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'userId' => $document->getId(),
|
||||
'userInternalId' => $document->getInternalId(),
|
||||
'userInternalId' => $document->getSequence(),
|
||||
'providerType' => MESSAGE_TYPE_SMS,
|
||||
'identifier' => $document->getAttribute('phone'),
|
||||
]);
|
||||
|
||||
@@ -29,12 +29,12 @@ class V21 extends Migration
|
||||
}
|
||||
|
||||
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
|
||||
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
|
||||
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
|
||||
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCollections();
|
||||
|
||||
if ($this->project->getInternalId() !== 'console') {
|
||||
if ($this->project->getSequence() !== 'console') {
|
||||
Console::info('Migrating Buckets');
|
||||
$this->migrateBuckets();
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class V21 extends Migration
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
$internalProjectId = $this->project->getSequence();
|
||||
$collectionType = match ($internalProjectId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
@@ -251,7 +251,7 @@ class V21 extends Migration
|
||||
private function migrateBuckets(): void
|
||||
{
|
||||
$this->dbForProject->forEach('buckets', function (Document $bucket) {
|
||||
$bucketId = 'bucket_' . $bucket['$internalId'];
|
||||
$bucketId = 'bucket_' . $bucket['$sequence'];
|
||||
|
||||
Console::log("Migrating Bucket {$bucketId} {$bucket->getId()} ({$bucket->getAttribute('name')})");
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class V22 extends Migration
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
$projectInternalId = $this->project->getSequence();
|
||||
|
||||
if (empty($projectInternalId)) {
|
||||
throw new Exception('Project ID is null');
|
||||
@@ -150,9 +150,9 @@ class V22 extends Migration
|
||||
];
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
@@ -412,7 +412,7 @@ class V22 extends Migration
|
||||
2. Fill "deploymentCreatedAt" with deployment's "$createdAt"
|
||||
--- Fetch latestDeployment using find()
|
||||
3. Fill latestDeploymentId with latestDeployment's "$id"
|
||||
4. Fill latestDeploymentInternalId with latestDeployment's "$internalId"
|
||||
4. Fill latestDeploymentInternalId with latestDeployment's "$sequence"
|
||||
5. Fill latestDeploymentCreatedAt with latestDeployment's "$createdAt"
|
||||
6. Fill latestDeploymentStatus with latestDeployment's build's "status"
|
||||
*/
|
||||
@@ -451,7 +451,7 @@ class V22 extends Migration
|
||||
|
||||
$document
|
||||
->setAttribute('latestDeploymentId', $latestDeployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->getInternalId())
|
||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $latestBuild->getAttribute('status', $document->getAttribute('latestDeploymentStatus', '')));
|
||||
break;
|
||||
@@ -515,7 +515,7 @@ class V22 extends Migration
|
||||
|
||||
private function cleanCollections(): void
|
||||
{
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
$projectInternalId = $this->project->getSequence();
|
||||
|
||||
$collectionType = match ($projectInternalId) {
|
||||
'console' => 'console',
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Appwrite\Platform\Modules\Compute;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Query;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
@@ -68,13 +69,13 @@ class Base extends Action
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'resourceId' => $function->getId(),
|
||||
'resourceInternalId' => $function->getInternalId(),
|
||||
'resourceInternalId' => $function->getSequence(),
|
||||
'resourceType' => 'functions',
|
||||
'entrypoint' => $entrypoint,
|
||||
'buildCommands' => $function->getAttribute('commands', ''),
|
||||
'type' => 'vcs',
|
||||
'installationId' => $installation->getId(),
|
||||
'installationInternalId' => $installation->getInternalId(),
|
||||
'installationInternalId' => $installation->getSequence(),
|
||||
'providerRepositoryId' => $providerRepositoryId,
|
||||
'repositoryId' => $function->getAttribute('repositoryId', ''),
|
||||
'repositoryInternalId' => $function->getAttribute('repositoryInternalId', ''),
|
||||
@@ -94,7 +95,7 @@ class Base extends Action
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
@@ -165,7 +166,7 @@ class Base extends Action
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'resourceId' => $site->getId(),
|
||||
'resourceInternalId' => $site->getInternalId(),
|
||||
'resourceInternalId' => $site->getSequence(),
|
||||
'resourceType' => 'sites',
|
||||
'buildCommands' => implode(' && ', $commands),
|
||||
'buildOutput' => $site->getAttribute('outputDirectory', ''),
|
||||
@@ -173,7 +174,7 @@ class Base extends Action
|
||||
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
|
||||
'type' => 'vcs',
|
||||
'installationId' => $installation->getId(),
|
||||
'installationInternalId' => $installation->getInternalId(),
|
||||
'installationInternalId' => $installation->getSequence(),
|
||||
'providerRepositoryId' => $providerRepositoryId,
|
||||
'repositoryId' => $site->getAttribute('repositoryId', ''),
|
||||
'repositoryInternalId' => $site->getAttribute('repositoryInternalId', ''),
|
||||
@@ -193,7 +194,7 @@ class Base extends Action
|
||||
|
||||
$site = $site
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('sites', $site->getId(), $site);
|
||||
@@ -208,15 +209,15 @@ class Base extends Action
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'domain' => $domain,
|
||||
'trigger' => 'deployment',
|
||||
'type' => 'deployment',
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentInternalId' => $deployment->getSequence(),
|
||||
'deploymentResourceType' => 'site',
|
||||
'deploymentResourceId' => $site->getId(),
|
||||
'deploymentResourceInternalId' => $site->getInternalId(),
|
||||
'deploymentResourceInternalId' => $site->getSequence(),
|
||||
'deploymentVcsProviderBranch' => $providerBranch,
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
@@ -234,4 +235,38 @@ class Base extends Action
|
||||
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
protected function listRules(Document $project, array $queries, Database $database, callable $callback): void
|
||||
{
|
||||
$limit = 100;
|
||||
$cursor = null;
|
||||
|
||||
do {
|
||||
$queries = \array_merge([
|
||||
Query::limit($limit),
|
||||
Query::equal("projectInternalId", [$project->getSequence()])
|
||||
], $queries);
|
||||
|
||||
if ($cursor !== null) {
|
||||
$queries[] = Query::cursorAfter($cursor);
|
||||
}
|
||||
|
||||
$results = $database->find('rules', $queries);
|
||||
|
||||
$total = \count($results);
|
||||
if ($total > 0) {
|
||||
$cursor = $results[$total - 1];
|
||||
}
|
||||
|
||||
if ($total < $limit) {
|
||||
$cursor = null;
|
||||
}
|
||||
|
||||
foreach ($results as $document) {
|
||||
if (is_callable($callback)) {
|
||||
$callback($document);
|
||||
}
|
||||
}
|
||||
} while (!\is_null($cursor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ class Create extends Action
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'resourceInternalId' => $function->getInternalId(),
|
||||
'resourceInternalId' => $function->getSequence(),
|
||||
'resourceId' => $function->getId(),
|
||||
'resourceType' => 'functions',
|
||||
'entrypoint' => $entrypoint,
|
||||
@@ -252,7 +252,7 @@ class Create extends Action
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
@@ -274,7 +274,7 @@ class Create extends Action
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'resourceInternalId' => $function->getInternalId(),
|
||||
'resourceInternalId' => $function->getSequence(),
|
||||
'resourceId' => $function->getId(),
|
||||
'resourceType' => 'functions',
|
||||
'entrypoint' => $entrypoint,
|
||||
@@ -291,7 +291,7 @@ class Create extends Action
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user