Compare commits

..
Author SHA1 Message Date
Matej Bačo c3f8f960d2 Mark edge differences 2025-06-04 12:56:58 +02:00
154 changed files with 2658 additions and 174637 deletions
+1 -7
View File
@@ -8,10 +8,4 @@ reviews:
base_branches:
- main
- 1.6.x
- 1.7.x
- 1.8.x
high_level_summary: false
poem: false
sequence_diagrams: false
collapse_walkthrough: true
changed_files_summary: false
- 1.7.x
+2 -2
View File
@@ -198,7 +198,7 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude=devKeys
e2e_shared_mode_test:
name: E2E Shared Mode Service Test
@@ -277,7 +277,7 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude=devKeys
e2e_dev_keys:
name: E2E Service Test (Dev Keys)
+5 -5
View File
@@ -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->getSequence(), METRIC_BUCKET_ID_FILES)));
$storage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getSequence(), METRIC_BUCKET_ID_FILES_STORAGE)));
$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)));
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->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)
->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)
->setProject($project)
->trigger();
```
+8 -9
View File
@@ -125,13 +125,13 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
return $database;
@@ -145,13 +145,13 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
$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((int)$project->getSequence());
$database->setTenant($project->getInternalId());
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((int)$project->getSequence());
$database->setTenant($project->getInternalId());
}
return $database;
@@ -251,7 +251,7 @@ CLI::setResource('logError', function (Registry $register) {
};
}, ['register']);
CLI::setResource('executor', fn () => new Executor());
CLI::setResource('executor', fn () => new Executor(fn (string $projectId, string $deploymentId) => System::getEnv('_APP_EXECUTOR_HOST')));
CLI::setResource('telemetry', fn () => new NoTelemetry());
@@ -284,6 +284,5 @@ $cli
$cli->shutdown()->action(fn () => Timer::clearAll());
// Enable coroutines, but disable TCP hooks. These don't work until we use `\Utopia\Cache\Adapter\Pool` and `\Utopia\Database\Adapter\Pool`.
Runtime::enableCoroutine(SWOOLE_HOOK_ALL ^ SWOOLE_HOOK_TCP);
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
run($cli->run(...));
-1
View File
@@ -1286,7 +1286,6 @@ return [
]
],
],
'deployments' => [
'$collection' => ID::custom(Database::METADATA),
'$id' => ID::custom('deployments'),
+1 -1
View File
@@ -11,7 +11,7 @@ use Utopia\System\System;
$console = [
'$id' => ID::custom('console'),
'$sequence' => ID::custom('console'),
'$internalId' => ID::custom('console'),
'name' => 'Appwrite',
'$collection' => ID::custom('projects'),
'description' => 'Appwrite core engine',
+4 -9
View File
@@ -59,7 +59,7 @@ return [
[
'key' => 'flutter',
'name' => 'Flutter',
'version' => '17.0.1',
'version' => '16.1.0',
'url' => 'https://github.com/appwrite/sdk-for-flutter',
'package' => 'https://pub.dev/packages/appwrite',
'enabled' => true,
@@ -77,7 +77,7 @@ return [
[
'key' => 'apple',
'name' => 'Apple',
'version' => '10.1.1',
'version' => '10.1.0',
'url' => 'https://github.com/appwrite/sdk-for-apple',
'package' => 'https://github.com/appwrite/sdk-for-apple',
'enabled' => true,
@@ -217,7 +217,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '8.0.1',
'version' => '7.0.0',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://www.npmjs.com/package/appwrite-cli',
'enabled' => true,
@@ -231,11 +231,6 @@ return [
'gitRepoName' => 'sdk-for-cli',
'gitUserName' => 'appwrite',
'gitBranch' => 'dev',
'exclude' => [
'services' => [
['name' => 'assistant'],
],
],
],
],
],
@@ -416,7 +411,7 @@ return [
[
'key' => 'swift',
'name' => 'Swift',
'version' => '10.1.0',
'version' => '10.0.0',
'url' => 'https://github.com/appwrite/sdk-for-swift',
'package' => 'https://github.com/appwrite/sdk-for-swift',
'enabled' => true,
+2 -3
View File
@@ -4666,7 +4666,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -6595,8 +6595,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
+11 -52
View File
@@ -8071,7 +8071,7 @@
"model": "#\/components\/schemas\/documentList"
}
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate 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."
"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": {
@@ -8151,7 +8151,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update 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.",
"description": "Create or update 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.\n",
"responses": {
"200": {
"description": "Documents List",
@@ -8242,7 +8242,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nUpdate all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"description": "Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"responses": {
"200": {
"description": "Documents List",
@@ -8335,7 +8335,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nBulk delete documents using queries, if no queries are passed then all documents are deleted.",
"description": "Bulk delete documents using queries, if no queries are passed then all documents are deleted.",
"responses": {
"200": {
"description": "Documents List",
@@ -8520,7 +8520,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -9767,7 +9767,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -9793,8 +9792,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -10397,7 +10395,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -10423,8 +10420,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -25450,33 +25446,12 @@
"Temporary Redirect 307",
"Permanent Redirect 308"
]
},
"resourceId": {
"type": "string",
"description": "ID of parent resource.",
"x-example": "<RESOURCE_ID>"
},
"resourceType": {
"type": "string",
"description": "Type of parent resource.",
"x-example": "site",
"enum": [
"site",
"function"
],
"x-enum-name": "ProxyResourceType",
"x-enum-keys": [
"Site",
"Function"
]
}
},
"required": [
"domain",
"url",
"statusCode",
"resourceId",
"resourceType"
"statusCode"
]
}
}
@@ -25961,7 +25936,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -25987,8 +25961,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -26607,7 +26580,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -26633,8 +26605,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -29393,8 +29364,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
@@ -34876,17 +34846,6 @@
"default": ""
},
"in": "query"
},
{
"name": "providerReference",
"description": "Git reference (branch, tag, commit) to get contents from",
"required": false,
"schema": {
"type": "string",
"x-example": "<PROVIDER_REFERENCE>",
"default": ""
},
"in": "query"
}
]
}
+10 -19
View File
@@ -7552,7 +7552,7 @@
"model": "#\/components\/schemas\/documentList"
}
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate 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."
"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": {
@@ -7634,7 +7634,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update 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.",
"description": "Create or update 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.\n",
"responses": {
"200": {
"description": "Documents List",
@@ -7726,7 +7726,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nUpdate all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"description": "Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"responses": {
"200": {
"description": "Documents List",
@@ -7820,7 +7820,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nBulk delete documents using queries, if no queries are passed then all documents are deleted.",
"description": "Bulk delete documents using queries, if no queries are passed then all documents are deleted.",
"responses": {
"200": {
"description": "Documents List",
@@ -8008,7 +8008,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -8844,7 +8844,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -8870,8 +8869,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -9246,7 +9244,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -9272,8 +9269,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -17494,7 +17490,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -17520,8 +17515,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -17912,7 +17906,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -17938,8 +17931,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -20654,8 +20646,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+39 -279
View File
@@ -4457,7 +4457,6 @@
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
"scope": "documents.write",
"platforms": [
"console",
"client",
"server",
"server"
@@ -4467,7 +4466,6 @@
{
"name": "createDocument",
"auth": {
"Admin": [],
"Session": [],
"Key": [],
"JWT": []
@@ -4668,7 +4666,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -4892,7 +4890,7 @@
"x-appwrite": {
"method": "deleteDocument",
"group": "documents",
"weight": 119,
"weight": 117,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4953,236 +4951,6 @@
]
}
},
"\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/decrement": {
"patch": {
"summary": "Decrement document attribute",
"operationId": "databasesDecrementDocumentAttribute",
"tags": [
"databases"
],
"description": "Decrement a specific attribute of a document by a given value.",
"responses": {
"200": {
"description": "Document",
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/document"
}
}
}
}
},
"x-appwrite": {
"method": "decrementDocumentAttribute",
"group": "documents",
"weight": 116,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "databases\/decrement-document-attribute.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/decrement-document-attribute.md",
"rate-limit": 120,
"rate-time": 60,
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
"scope": "documents.write",
"platforms": [
"console",
"server",
"client",
"server"
],
"packaging": false,
"auth": {
"Project": []
}
},
"security": [
{
"Project": [],
"Session": [],
"JWT": []
}
],
"parameters": [
{
"name": "databaseId",
"description": "Database ID.",
"required": true,
"schema": {
"type": "string",
"x-example": "<DATABASE_ID>"
},
"in": "path"
},
{
"name": "collectionId",
"description": "Collection ID.",
"required": true,
"schema": {
"type": "string",
"x-example": "<COLLECTION_ID>"
},
"in": "path"
},
{
"name": "documentId",
"description": "Document ID.",
"required": true,
"schema": {
"type": "string",
"x-example": "<DOCUMENT_ID>"
},
"in": "path"
},
{
"name": "attribute",
"description": "Attribute key.",
"required": true,
"schema": {
"type": "string"
},
"in": "path"
}
],
"requestBody": {
"content": {
"application\/json": {
"schema": {
"type": "object",
"properties": {
"value": {
"type": "number",
"description": "Value to decrement the attribute by. The value must be a number.",
"x-example": null
},
"min": {
"type": "number",
"description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.",
"x-example": null
}
}
}
}
}
}
}
},
"\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/increment": {
"patch": {
"summary": "Increment document attribute",
"operationId": "databasesIncrementDocumentAttribute",
"tags": [
"databases"
],
"description": "Increment a specific attribute of a document by a given value.",
"responses": {
"200": {
"description": "Document",
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/document"
}
}
}
}
},
"x-appwrite": {
"method": "incrementDocumentAttribute",
"group": "documents",
"weight": 115,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "databases\/increment-document-attribute.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/increment-document-attribute.md",
"rate-limit": 120,
"rate-time": 60,
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
"scope": "documents.write",
"platforms": [
"console",
"server",
"client",
"server"
],
"packaging": false,
"auth": {
"Project": []
}
},
"security": [
{
"Project": [],
"Session": [],
"JWT": []
}
],
"parameters": [
{
"name": "databaseId",
"description": "Database ID.",
"required": true,
"schema": {
"type": "string",
"x-example": "<DATABASE_ID>"
},
"in": "path"
},
{
"name": "collectionId",
"description": "Collection ID.",
"required": true,
"schema": {
"type": "string",
"x-example": "<COLLECTION_ID>"
},
"in": "path"
},
{
"name": "documentId",
"description": "Document ID.",
"required": true,
"schema": {
"type": "string",
"x-example": "<DOCUMENT_ID>"
},
"in": "path"
},
{
"name": "attribute",
"description": "Attribute key.",
"required": true,
"schema": {
"type": "string"
},
"in": "path"
}
],
"requestBody": {
"content": {
"application\/json": {
"schema": {
"type": "object",
"properties": {
"value": {
"type": "number",
"description": "Value to increment the attribute by. The value must be a number.",
"x-example": null
},
"max": {
"type": "number",
"description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.",
"x-example": null
}
}
}
}
}
}
}
},
"\/functions\/{functionId}\/executions": {
"get": {
"summary": "List executions",
@@ -5206,7 +4974,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 394,
"weight": 392,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5281,7 +5049,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 392,
"weight": 390,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5396,7 +5164,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 393,
"weight": 391,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5470,7 +5238,7 @@
"x-appwrite": {
"method": "query",
"group": "graphql",
"weight": 308,
"weight": 306,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5522,7 +5290,7 @@
"x-appwrite": {
"method": "mutation",
"group": "graphql",
"weight": 307,
"weight": 305,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5574,7 +5342,7 @@
"x-appwrite": {
"method": "get",
"group": null,
"weight": 124,
"weight": 122,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5626,7 +5394,7 @@
"x-appwrite": {
"method": "listCodes",
"group": null,
"weight": 125,
"weight": 123,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5678,7 +5446,7 @@
"x-appwrite": {
"method": "listContinents",
"group": null,
"weight": 129,
"weight": 127,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5730,7 +5498,7 @@
"x-appwrite": {
"method": "listCountries",
"group": null,
"weight": 126,
"weight": 124,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5782,7 +5550,7 @@
"x-appwrite": {
"method": "listCountriesEU",
"group": null,
"weight": 127,
"weight": 125,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5834,7 +5602,7 @@
"x-appwrite": {
"method": "listCountriesPhones",
"group": null,
"weight": 128,
"weight": 126,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5886,7 +5654,7 @@
"x-appwrite": {
"method": "listCurrencies",
"group": null,
"weight": 130,
"weight": 128,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5938,7 +5706,7 @@
"x-appwrite": {
"method": "listLanguages",
"group": null,
"weight": 131,
"weight": 129,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5990,7 +5758,7 @@
"x-appwrite": {
"method": "createSubscriber",
"group": "subscribers",
"weight": 354,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6073,7 +5841,7 @@
"x-appwrite": {
"method": "deleteSubscriber",
"group": "subscribers",
"weight": 358,
"weight": 356,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6148,7 +5916,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 214,
"weight": 212,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6234,7 +6002,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 213,
"weight": 211,
"cookies": false,
"type": "upload",
"deprecated": false,
@@ -6332,7 +6100,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 215,
"weight": 213,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6404,7 +6172,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 220,
"weight": 218,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6493,7 +6261,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 221,
"weight": 219,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6560,7 +6328,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 217,
"weight": 215,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6638,7 +6406,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 216,
"weight": 214,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6827,8 +6595,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
@@ -6866,7 +6633,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 218,
"weight": 216,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6951,7 +6718,7 @@
"x-appwrite": {
"method": "list",
"group": "teams",
"weight": 225,
"weight": 223,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7027,7 +6794,7 @@
"x-appwrite": {
"method": "create",
"group": "teams",
"weight": 224,
"weight": 222,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7112,7 +6879,7 @@
"x-appwrite": {
"method": "get",
"group": "teams",
"weight": 226,
"weight": 224,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7174,7 +6941,7 @@
"x-appwrite": {
"method": "updateName",
"group": "teams",
"weight": 228,
"weight": 226,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7248,7 +7015,7 @@
"x-appwrite": {
"method": "delete",
"group": "teams",
"weight": 230,
"weight": 228,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7312,7 +7079,7 @@
"x-appwrite": {
"method": "listMemberships",
"group": "memberships",
"weight": 232,
"weight": 230,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7398,7 +7165,7 @@
"x-appwrite": {
"method": "createMembership",
"group": "memberships",
"weight": 231,
"weight": 229,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7509,7 +7276,7 @@
"x-appwrite": {
"method": "getMembership",
"group": "memberships",
"weight": 233,
"weight": 231,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7581,7 +7348,7 @@
"x-appwrite": {
"method": "updateMembership",
"group": "memberships",
"weight": 234,
"weight": 232,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7668,7 +7435,7 @@
"x-appwrite": {
"method": "deleteMembership",
"group": "memberships",
"weight": 236,
"weight": 234,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7742,7 +7509,7 @@
"x-appwrite": {
"method": "updateMembershipStatus",
"group": "memberships",
"weight": 235,
"weight": 233,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7840,7 +7607,7 @@
"x-appwrite": {
"method": "getPrefs",
"group": "teams",
"weight": 227,
"weight": 225,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7901,7 +7668,7 @@
"x-appwrite": {
"method": "updatePrefs",
"group": "teams",
"weight": 229,
"weight": 227,
"cookies": false,
"type": "",
"deprecated": false,
@@ -8415,12 +8182,6 @@
"description": "Document ID.",
"x-example": "5e5ea5c16897e"
},
"$sequence": {
"type": "integer",
"description": "Document automatically incrementing ID.",
"x-example": 1,
"format": "int32"
},
"$collectionId": {
"type": "string",
"description": "Collection ID.",
@@ -8455,7 +8216,6 @@
"additionalProperties": true,
"required": [
"$id",
"$sequence",
"$collectionId",
"$databaseId",
"$createdAt",
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -4809,7 +4809,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -6729,8 +6729,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
+11 -52
View File
@@ -8200,7 +8200,7 @@
"model": "#\/definitions\/documentList"
}
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate 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."
"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": {
@@ -8284,7 +8284,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update 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.",
"description": "Create or update 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.\n",
"responses": {
"200": {
"description": "Documents List",
@@ -8372,7 +8372,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nUpdate all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"description": "Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"responses": {
"200": {
"description": "Documents List",
@@ -8463,7 +8463,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nBulk delete documents using queries, if no queries are passed then all documents are deleted.",
"description": "Bulk delete documents using queries, if no queries are passed then all documents are deleted.",
"responses": {
"200": {
"description": "Documents List",
@@ -8638,7 +8638,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -9835,7 +9835,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -9861,8 +9860,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -10468,7 +10466,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -10494,8 +10491,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -25700,35 +25696,12 @@
"Temporary Redirect 307",
"Permanent Redirect 308"
]
},
"resourceId": {
"type": "string",
"description": "ID of parent resource.",
"default": null,
"x-example": "<RESOURCE_ID>"
},
"resourceType": {
"type": "string",
"description": "Type of parent resource.",
"default": null,
"x-example": "site",
"enum": [
"site",
"function"
],
"x-enum-name": "ProxyResourceType",
"x-enum-keys": [
"Site",
"Function"
]
}
},
"required": [
"domain",
"url",
"statusCode",
"resourceId",
"resourceType"
"statusCode"
]
}
}
@@ -26230,7 +26203,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -26256,8 +26228,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -26879,7 +26850,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -26905,8 +26875,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -29635,8 +29604,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
@@ -35095,15 +35063,6 @@
"x-example": "<PROVIDER_ROOT_DIRECTORY>",
"default": "",
"in": "query"
},
{
"name": "providerReference",
"description": "Git reference (branch, tag, commit) to get contents from",
"required": false,
"type": "string",
"x-example": "<PROVIDER_REFERENCE>",
"default": "",
"in": "query"
}
]
}
+10 -19
View File
@@ -7671,7 +7671,7 @@
"model": "#\/definitions\/documentList"
}
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate 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."
"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": {
@@ -7757,7 +7757,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update 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.",
"description": "Create or update 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.\n",
"responses": {
"200": {
"description": "Documents List",
@@ -7846,7 +7846,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nUpdate all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"description": "Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.",
"responses": {
"200": {
"description": "Documents List",
@@ -7938,7 +7938,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nBulk delete documents using queries, if no queries are passed then all documents are deleted.",
"description": "Bulk delete documents using queries, if no queries are passed then all documents are deleted.",
"responses": {
"200": {
"description": "Documents List",
@@ -8116,7 +8116,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -8927,7 +8927,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -8953,8 +8952,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -9342,7 +9340,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -9368,8 +9365,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -17796,7 +17792,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -17822,8 +17817,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -18227,7 +18221,6 @@
"dart-3.1",
"dart-3.3",
"dart-3.5",
"dart-3.8",
"dotnet-6.0",
"dotnet-7.0",
"dotnet-8.0",
@@ -18253,8 +18246,7 @@
"static-1",
"flutter-3.24",
"flutter-3.27",
"flutter-3.29",
"flutter-3.32"
"flutter-3.29"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -20943,8 +20935,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+89 -271
View File
@@ -3451,6 +3451,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -3575,6 +3576,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -3705,6 +3707,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -3767,6 +3770,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4253,6 +4257,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4335,6 +4340,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4425,6 +4431,7 @@
"scope": "avatars.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4515,6 +4522,7 @@
"scope": "documents.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4595,8 +4603,8 @@
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
"scope": "documents.write",
"platforms": [
"console",
"client",
"server",
"server"
],
"packaging": false,
@@ -4604,7 +4612,6 @@
{
"name": "createDocument",
"auth": {
"Admin": [],
"Session": [],
"Key": [],
"JWT": []
@@ -4736,6 +4743,7 @@
"scope": "documents.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4801,7 +4809,7 @@
"tags": [
"databases"
],
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate or update a 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.",
"description": "Create or update a 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.",
"responses": {
"200": {
"description": "Document",
@@ -4825,6 +4833,7 @@
"scope": "documents.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -4929,6 +4938,7 @@
"scope": "documents.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5013,7 +5023,7 @@
"x-appwrite": {
"method": "deleteDocument",
"group": "documents",
"weight": 119,
"weight": 117,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5025,6 +5035,7 @@
"scope": "documents.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5067,224 +5078,6 @@
]
}
},
"\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/decrement": {
"patch": {
"summary": "Decrement document attribute",
"operationId": "databasesDecrementDocumentAttribute",
"consumes": [
"application\/json"
],
"produces": [
"application\/json"
],
"tags": [
"databases"
],
"description": "Decrement a specific attribute of a document by a given value.",
"responses": {
"200": {
"description": "Document",
"schema": {
"$ref": "#\/definitions\/document"
}
}
},
"x-appwrite": {
"method": "decrementDocumentAttribute",
"group": "documents",
"weight": 116,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "databases\/decrement-document-attribute.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/decrement-document-attribute.md",
"rate-limit": 120,
"rate-time": 60,
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
"scope": "documents.write",
"platforms": [
"console",
"server",
"client",
"server"
],
"packaging": false,
"auth": {
"Project": []
}
},
"security": [
{
"Project": [],
"Session": [],
"JWT": []
}
],
"parameters": [
{
"name": "databaseId",
"description": "Database ID.",
"required": true,
"type": "string",
"x-example": "<DATABASE_ID>",
"in": "path"
},
{
"name": "collectionId",
"description": "Collection ID.",
"required": true,
"type": "string",
"x-example": "<COLLECTION_ID>",
"in": "path"
},
{
"name": "documentId",
"description": "Document ID.",
"required": true,
"type": "string",
"x-example": "<DOCUMENT_ID>",
"in": "path"
},
{
"name": "attribute",
"description": "Attribute key.",
"required": true,
"type": "string",
"in": "path"
},
{
"name": "payload",
"in": "body",
"schema": {
"type": "object",
"properties": {
"value": {
"type": "number",
"description": "Value to decrement the attribute by. The value must be a number.",
"default": 1,
"x-example": null
},
"min": {
"type": "number",
"description": "Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.",
"default": null,
"x-example": null
}
}
}
}
]
}
},
"\/databases\/{databaseId}\/collections\/{collectionId}\/documents\/{documentId}\/{attribute}\/increment": {
"patch": {
"summary": "Increment document attribute",
"operationId": "databasesIncrementDocumentAttribute",
"consumes": [
"application\/json"
],
"produces": [
"application\/json"
],
"tags": [
"databases"
],
"description": "Increment a specific attribute of a document by a given value.",
"responses": {
"200": {
"description": "Document",
"schema": {
"$ref": "#\/definitions\/document"
}
}
},
"x-appwrite": {
"method": "incrementDocumentAttribute",
"group": "documents",
"weight": 115,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "databases\/increment-document-attribute.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/databases\/increment-document-attribute.md",
"rate-limit": 120,
"rate-time": 60,
"rate-key": "ip:{ip},method:{method},url:{url},userId:{userId}",
"scope": "documents.write",
"platforms": [
"console",
"server",
"client",
"server"
],
"packaging": false,
"auth": {
"Project": []
}
},
"security": [
{
"Project": [],
"Session": [],
"JWT": []
}
],
"parameters": [
{
"name": "databaseId",
"description": "Database ID.",
"required": true,
"type": "string",
"x-example": "<DATABASE_ID>",
"in": "path"
},
{
"name": "collectionId",
"description": "Collection ID.",
"required": true,
"type": "string",
"x-example": "<COLLECTION_ID>",
"in": "path"
},
{
"name": "documentId",
"description": "Document ID.",
"required": true,
"type": "string",
"x-example": "<DOCUMENT_ID>",
"in": "path"
},
{
"name": "attribute",
"description": "Attribute key.",
"required": true,
"type": "string",
"in": "path"
},
{
"name": "payload",
"in": "body",
"schema": {
"type": "object",
"properties": {
"value": {
"type": "number",
"description": "Value to increment the attribute by. The value must be a number.",
"default": 1,
"x-example": null
},
"max": {
"type": "number",
"description": "Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.",
"default": null,
"x-example": null
}
}
}
}
]
}
},
"\/functions\/{functionId}\/executions": {
"get": {
"summary": "List executions",
@@ -5308,7 +5101,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 394,
"weight": 392,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5320,6 +5113,7 @@
"scope": "execution.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5381,7 +5175,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 392,
"weight": 390,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5393,6 +5187,7 @@
"scope": "execution.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5497,7 +5292,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 393,
"weight": 391,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5509,6 +5304,7 @@
"scope": "execution.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5568,7 +5364,7 @@
"x-appwrite": {
"method": "query",
"group": "graphql",
"weight": 308,
"weight": 306,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5580,7 +5376,8 @@
"scope": "graphql",
"platforms": [
"server",
"client"
"client",
"server"
],
"packaging": false,
"auth": {
@@ -5641,7 +5438,7 @@
"x-appwrite": {
"method": "mutation",
"group": "graphql",
"weight": 307,
"weight": 305,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5653,7 +5450,8 @@
"scope": "graphql",
"platforms": [
"server",
"client"
"client",
"server"
],
"packaging": false,
"auth": {
@@ -5712,7 +5510,7 @@
"x-appwrite": {
"method": "get",
"group": null,
"weight": 124,
"weight": 122,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5724,6 +5522,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5763,7 +5562,7 @@
"x-appwrite": {
"method": "listCodes",
"group": null,
"weight": 125,
"weight": 123,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5775,6 +5574,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5814,7 +5614,7 @@
"x-appwrite": {
"method": "listContinents",
"group": null,
"weight": 129,
"weight": 127,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5826,6 +5626,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5865,7 +5666,7 @@
"x-appwrite": {
"method": "listCountries",
"group": null,
"weight": 126,
"weight": 124,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5877,6 +5678,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5916,7 +5718,7 @@
"x-appwrite": {
"method": "listCountriesEU",
"group": null,
"weight": 127,
"weight": 125,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5928,6 +5730,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -5967,7 +5770,7 @@
"x-appwrite": {
"method": "listCountriesPhones",
"group": null,
"weight": 128,
"weight": 126,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5979,6 +5782,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6018,7 +5822,7 @@
"x-appwrite": {
"method": "listCurrencies",
"group": null,
"weight": 130,
"weight": 128,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6030,6 +5834,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6069,7 +5874,7 @@
"x-appwrite": {
"method": "listLanguages",
"group": null,
"weight": 131,
"weight": 129,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6081,6 +5886,7 @@
"scope": "locale.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6122,7 +5928,7 @@
"x-appwrite": {
"method": "createSubscriber",
"group": "subscribers",
"weight": 354,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6135,7 +5941,8 @@
"platforms": [
"server",
"client",
"console"
"console",
"server"
],
"packaging": false,
"auth": {
@@ -6206,7 +6013,7 @@
"x-appwrite": {
"method": "deleteSubscriber",
"group": "subscribers",
"weight": 358,
"weight": 356,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6219,7 +6026,8 @@
"platforms": [
"server",
"client",
"console"
"console",
"server"
],
"packaging": false,
"auth": {
@@ -6276,7 +6084,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 214,
"weight": 212,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6288,6 +6096,7 @@
"scope": "files.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6358,7 +6167,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 213,
"weight": 211,
"cookies": false,
"type": "upload",
"deprecated": false,
@@ -6370,6 +6179,7 @@
"scope": "files.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6447,7 +6257,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 215,
"weight": 213,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6459,6 +6269,7 @@
"scope": "files.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6516,7 +6327,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 220,
"weight": 218,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6528,6 +6339,7 @@
"scope": "files.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6604,7 +6416,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 221,
"weight": 219,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6616,6 +6428,7 @@
"scope": "files.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6673,7 +6486,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 217,
"weight": 215,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6685,6 +6498,7 @@
"scope": "files.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6751,7 +6565,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 216,
"weight": 214,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6763,6 +6577,7 @@
"scope": "files.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -6914,8 +6729,7 @@
"png",
"webp",
"heic",
"avif",
"gif"
"avif"
],
"x-enum-name": "ImageFormat",
"x-enum-keys": [],
@@ -6957,7 +6771,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 218,
"weight": 216,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6969,6 +6783,7 @@
"scope": "files.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7035,7 +6850,7 @@
"x-appwrite": {
"method": "list",
"group": "teams",
"weight": 225,
"weight": 223,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7047,6 +6862,7 @@
"scope": "teams.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7109,7 +6925,7 @@
"x-appwrite": {
"method": "create",
"group": "teams",
"weight": 224,
"weight": 222,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7121,6 +6937,7 @@
"scope": "teams.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7198,7 +7015,7 @@
"x-appwrite": {
"method": "get",
"group": "teams",
"weight": 226,
"weight": 224,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7210,6 +7027,7 @@
"scope": "teams.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7259,7 +7077,7 @@
"x-appwrite": {
"method": "updateName",
"group": "teams",
"weight": 228,
"weight": 226,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7271,6 +7089,7 @@
"scope": "teams.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7333,7 +7152,7 @@
"x-appwrite": {
"method": "delete",
"group": "teams",
"weight": 230,
"weight": 228,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7345,6 +7164,7 @@
"scope": "teams.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7394,7 +7214,7 @@
"x-appwrite": {
"method": "listMemberships",
"group": "memberships",
"weight": 232,
"weight": 230,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7406,6 +7226,7 @@
"scope": "teams.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7476,7 +7297,7 @@
"x-appwrite": {
"method": "createMembership",
"group": "memberships",
"weight": 231,
"weight": 229,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7488,6 +7309,7 @@
"scope": "teams.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7588,7 +7410,7 @@
"x-appwrite": {
"method": "getMembership",
"group": "memberships",
"weight": 233,
"weight": 231,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7600,6 +7422,7 @@
"scope": "teams.read",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7657,7 +7480,7 @@
"x-appwrite": {
"method": "updateMembership",
"group": "memberships",
"weight": 234,
"weight": 232,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7669,6 +7492,7 @@
"scope": "teams.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7742,7 +7566,7 @@
"x-appwrite": {
"method": "deleteMembership",
"group": "memberships",
"weight": 236,
"weight": 234,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7754,6 +7578,7 @@
"scope": "teams.write",
"platforms": [
"client",
"server",
"server"
],
"packaging": false,
@@ -7813,7 +7638,7 @@
"x-appwrite": {
"method": "updateMembershipStatus",
"group": "memberships",
"weight": 235,
"weight": 233,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7907,7 +7732,7 @@
"x-appwrite": {
"method": "getPrefs",
"group": "teams",
"weight": 227,
"weight": 225,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7968,7 +7793,7 @@
"x-appwrite": {
"method": "updatePrefs",
"group": "teams",
"weight": 229,
"weight": 227,
"cookies": false,
"type": "",
"deprecated": false,
@@ -8460,12 +8285,6 @@
"description": "Document ID.",
"x-example": "5e5ea5c16897e"
},
"$sequence": {
"type": "integer",
"description": "Document automatically incrementing ID.",
"x-example": 1,
"format": "int32"
},
"$collectionId": {
"type": "string",
"description": "Collection ID.",
@@ -8500,7 +8319,6 @@
"additionalProperties": true,
"required": [
"$id",
"$sequence",
"$collectionId",
"$databaseId",
"$createdAt",
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+38 -38
View File
@@ -190,7 +190,7 @@ $createSession = function (string $userId, string $secret, Request $request, Res
[
'$id' => ID::unique(),
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'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('$sequence');
$user->removeAttribute('$internalId');
$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->getSequence(),
'userInternalId' => $user->getInternalId(),
'providerType' => MESSAGE_TYPE_EMAIL,
'identifier' => $email,
])));
@@ -907,7 +907,7 @@ App::post('/v1/account/sessions/email')
[
'$id' => ID::unique(),
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'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('$sequence');
$user->removeAttribute('$internalId');
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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence()),
Query::notEqual('userInternalId', $user->getInternalId()),
]);
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('$sequence');
$user->removeAttribute('$internalId');
$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->getSequence(),
'userInternalId' => $userDoc->getInternalId(),
'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->getSequence()]),
Query::equal('userInternalId', [$user->getInternalId()]),
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->getSequence()),
Query::notEqual('userInternalId', $user->getInternalId()),
]);
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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence());
->setAttribute('sessionInternalId', $session->getInternalId());
$dbForProject->updateDocument('targets', $target->getId(), $target);
}
@@ -1931,7 +1931,7 @@ App::post('/v1/account/tokens/magic-url')
'accessedAt' => DateTime::now(),
]);
$user->removeAttribute('$sequence');
$user->removeAttribute('$internalId');
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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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('$sequence');
$user->removeAttribute('$internalId');
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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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('$sequence');
$user->removeAttribute('$internalId');
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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(), $queries);
$logs = $audit->getLogsByUser($user->getInternalId(), $queries);
$output = [];
@@ -2732,7 +2732,7 @@ App::get('/v1/account/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByUser($user->getSequence(), $queries),
'total' => $audit->countLogsByUser($user->getInternalId(), $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->getSequence()),
Query::notEqual('userInternalId', $user->getInternalId()),
]);
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->getSequence(),
'userInternalId' => $profile->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'type' => Auth::TOKEN_TYPE_PHONE,
'secret' => Auth::hash($secret),
'expire' => $expire,
@@ -3880,7 +3880,7 @@ App::patch('/v1/account/mfa')
if ($user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false)) {
$factors[] = Type::PHONE;
}
$factors = \array_values(\array_unique($factors));
$factors = \array_unique($factors);
$session->setAttribute('factors', $factors);
$dbForProject->updateDocument('sessions', $session->getId(), $session);
@@ -3979,7 +3979,7 @@ App::post('/v1/account/mfa/authenticators/:type')
$authenticator = new Document([
'$id' => ID::unique(),
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'type' => Type::TOTP,
'verified' => false,
'data' => [
@@ -4065,7 +4065,7 @@ App::put('/v1/account/mfa/authenticators/:type')
$factors = $session->getAttribute('factors', []);
$factors[] = $type;
$factors = \array_values(\array_unique($factors));
$factors = \array_unique($factors);
$session->setAttribute('factors', $factors);
$dbForProject->updateDocument('sessions', $session->getId(), $session);
@@ -4292,7 +4292,7 @@ App::post('/v1/account/mfa/challenge')
$code = Auth::codeGenerator();
$challenge = new Document([
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'type' => $factor,
'token' => Auth::tokenGenerator(),
'code' => $code,
@@ -4549,7 +4549,7 @@ App::put('/v1/account/mfa/challenge')
$factors = $session->getAttribute('factors', []);
$factors[] = $type;
$factors = \array_values(\array_unique($factors));
$factors = \array_unique($factors);
$session
->setAttribute('factors', $factors)
@@ -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->getSequence() : null,
'providerInternalId' => !empty($providerId) ? $provider->getInternalId() : null,
'providerType' => MESSAGE_TYPE_PUSH,
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'sessionId' => $session->getId(),
'sessionInternalId' => $session->getSequence(),
'sessionInternalId' => $session->getInternalId(),
'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->getSequence() !== $target->getAttribute('userInternalId')) {
if ($user->getInternalId() !== $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->getSequence()]);
$queries[] = Query::equal('userInternalId', [$user->getInternalId()]);
/**
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
+6 -6
View File
@@ -669,7 +669,7 @@ App::get('/v1/cards/cloud')
}
}
$isPlatinum = $user->getSequence() % 100 === 0;
$isPlatinum = $user->getInternalId() % 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->getSequence() % 100 === 0;
$isPlatinum = $user->getInternalId() % 100 === 0;
} else {
$userId = '63e0bcf3c3eb803ba530';
@@ -926,9 +926,9 @@ App::get('/v1/cards/cloud-og')
}
if (!$mock) {
$sequence = $user->getSequence();
$bgVariation = $sequence % 3 === 0 ? '1' : ($sequence % 3 === 1 ? '2' : '3');
$cardVariation = $sequence % 3 === 0 ? '1' : ($sequence % 3 === 1 ? '2' : '3');
$internalId = $user->getInternalId();
$bgVariation = $internalId % 3 === 0 ? '1' : ($internalId % 3 === 1 ? '2' : '3');
$cardVariation = $internalId % 3 === 0 ? '1' : ($internalId % 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->getSequence() % 100 === 0;
$isPlatinum = $user->getInternalId() % 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');
File diff suppressed because it is too large Load Diff
+3 -6
View File
@@ -845,18 +845,15 @@ App::get('/v1/health/storage')
$checkStart = \microtime(true);
foreach ($devices as $device) {
$uniqueFileName = \uniqid('health', true);
$filePath = $device->getPath($uniqueFileName);
if (!$device->write($filePath, 'test', 'text/plain')) {
if (!$device->write($device->getPath('health.txt'), 'test', 'text/plain')) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot());
}
if ($device->read($filePath) !== 'test') {
if ($device->read($device->getPath('health.txt')) !== 'test') {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot());
}
if (!$device->delete($filePath)) {
if (!$device->delete($device->getPath('health.txt'))) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot());
}
}
+14 -14
View File
@@ -2511,11 +2511,11 @@ App::post('/v1/messaging/topics/:topicId/subscribers')
Permission::delete(Role::user($user->getId())),
],
'topicId' => $topicId,
'topicInternalId' => $topic->getSequence(),
'topicInternalId' => $topic->getInternalId(),
'targetId' => $targetId,
'targetInternalId' => $target->getSequence(),
'targetInternalId' => $target->getInternalId(),
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence()]);
$queries[] = Query::equal('topicInternalId', [$topic->getInternalId()]);
/**
* 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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(),
'resourceInternalId' => $message->getInternalId(),
'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->getSequence(),
'resourceInternalId' => $message->getInternalId(),
'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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(),
'resourceInternalId' => $message->getInternalId(),
'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->getSequence(),
'resourceInternalId' => $message->getInternalId(),
'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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(),
'resourceInternalId' => $message->getInternalId(),
'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->getSequence(),
'resourceInternalId' => $message->getInternalId(),
'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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
if ($file->isEmpty()) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
+1 -1
View File
@@ -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->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
if ($file->isEmpty()) {
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
+9 -9
View File
@@ -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->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS);
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], 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->getSequence(), METRIC_BUCKET_ID_FILES_STORAGE);
$metric = str_replace('{bucketInternalId}', $bucket->getInternalId(), 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->getSequence(), METRIC_DATABASE_ID_STORAGE);
$metric = str_replace('{databaseInternalId}', $database->getInternalId(), 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->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE);
$deploymentMetric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE);
$buildMetric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
$metric = str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS);
$value = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
Query::equal('period', ['inf'])
+23 -23
View File
@@ -182,7 +182,7 @@ App::post('/v1/projects')
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'name' => $name,
'teamInternalId' => $team->getSequence(),
'teamInternalId' => $team->getInternalId(),
'teamId' => $team->getId(),
'region' => $region,
'description' => $description,
@@ -230,13 +230,13 @@ App::post('/v1/projects')
if ($sharedTables) {
$dbForProject
->setSharedTables(true)
->setTenant($sharedTablesV1 ? (int)$project->getSequence() : null)
->setTenant($sharedTablesV1 ? $project->getInternalId() : null)
->setNamespace($dsn->getParam('namespace'));
} else {
$dbForProject
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
$create = true;
@@ -504,12 +504,12 @@ App::patch('/v1/projects/:projectId/team')
$project
->setAttribute('teamId', $teamId)
->setAttribute('teamInternalId', $team->getSequence())
->setAttribute('teamInternalId', $team->getInternalId())
->setAttribute('$permissions', $permissions);
$project = $dbForPlatform->updateDocument('projects', $project->getId(), $project);
$installations = $dbForPlatform->find('installations', [
Query::equal('projectInternalId', [$project->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence(),
'projectInternalId' => $project->getInternalId(),
'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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
if ($webhook->isEmpty()) {
@@ -1528,7 +1528,7 @@ App::post('/v1/projects/:projectId/keys')
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
if ($key->isEmpty()) {
@@ -1811,7 +1811,7 @@ App::post('/v1/projects/:projectId/platforms')
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
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->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
]);
if ($platform->isEmpty()) {
+4 -4
View File
@@ -58,7 +58,7 @@ App::get('/v1/proxy/rules')
$queries[] = Query::search('search', $search);
}
$queries[] = Query::equal('projectInternalId', [$project->getSequence()]);
$queries[] = Query::equal('projectInternalId', [$project->getInternalId()]);
/**
* 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->getSequence()) {
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getInternalId()) {
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->getSequence()) {
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getInternalId()) {
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->getSequence()) {
if ($rule->isEmpty() || $rule->getAttribute('projectInternalId') !== $project->getInternalId()) {
throw new Exception(Exception::RULE_NOT_FOUND);
}
+79 -79
View File
@@ -145,7 +145,7 @@ App::post('/v1/storage/buckets')
$bucket = $dbForProject->getDocument('buckets', $bucketId);
$dbForProject->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes, permissions: $permissions ?? [], documentSecurity: $fileSecurity);
$dbForProject->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes, permissions: $permissions ?? [], documentSecurity: $fileSecurity);
} catch (DuplicateException) {
throw new Exception(Exception::STORAGE_BUCKET_ALREADY_EXISTS);
}
@@ -316,17 +316,17 @@ App::put('/v1/storage/buckets/:bucketId')
$permissions = Permission::aggregate($permissions);
$bucket = $dbForProject->updateDocument('buckets', $bucket->getId(), $bucket
->setAttribute('name', $name)
->setAttribute('$permissions', $permissions)
->setAttribute('maximumFileSize', $maximumFileSize)
->setAttribute('allowedFileExtensions', $allowedFileExtensions)
->setAttribute('fileSecurity', $fileSecurity)
->setAttribute('enabled', $enabled)
->setAttribute('encryption', $encryption)
->setAttribute('compression', $compression)
->setAttribute('antivirus', $antivirus));
->setAttribute('name', $name)
->setAttribute('$permissions', $permissions)
->setAttribute('maximumFileSize', $maximumFileSize)
->setAttribute('allowedFileExtensions', $allowedFileExtensions)
->setAttribute('fileSecurity', $fileSecurity)
->setAttribute('enabled', $enabled)
->setAttribute('encryption', $encryption)
->setAttribute('compression', $compression)
->setAttribute('antivirus', $antivirus));
$dbForProject->updateCollection('bucket_' . $bucket->getSequence(), $permissions, $fileSecurity);
$dbForProject->updateCollection('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(),
'bucketInternalId' => $bucket->getInternalId(),
'name' => $fileName,
'path' => $path,
'signature' => $fileHash,
@@ -671,7 +671,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
'metadata' => $metadata,
]);
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
$file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId, $file));
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(),
'bucketInternalId' => $bucket->getInternalId(),
'name' => $fileName,
'path' => $path,
'signature' => '',
@@ -720,7 +720,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
]);
try {
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
$file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId, $file));
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId);
$cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
}
if ($cursorDocument->isEmpty()) {
@@ -842,11 +842,11 @@ App::get('/v1/storage/buckets/:bucketId/files')
try {
if ($fileSecurity && !$valid) {
$files = $dbForProject->find('bucket_' . $bucket->getSequence(), $queries);
$total = $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT);
$files = $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries);
$total = $dbForProject->count('bucket_' . $bucket->getInternalId(), $filterQueries, APP_LIMIT_COUNT);
} else {
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getSequence(), $queries));
$total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT));
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getInternalId(), $queries));
$total = Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence();
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
$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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
}
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
@@ -1004,7 +1004,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
$algorithm = $file->getAttribute('algorithm', Compression::NONE);
$cipher = $file->getAttribute('openSSLCipher');
$mime = $file->getAttribute('mimeType');
if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) System::getEnv('_APP_STORAGE_PREVIEW_LIMIT', 20000000)) {
if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) System::getEnv('_APP_STORAGE_PREVIEW_LIMIT', APP_STORAGE_READ_BUFFER)) {
if (!\in_array($mime, $inputs)) {
$path = (\array_key_exists($mime, $fileLogos)) ? $fileLogos[$mime] : $fileLogos['default'];
} else {
@@ -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->getSequence();
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
$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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
}
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
@@ -1178,13 +1178,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND, 'File not found in ' . $path);
}
$response
->setContentType($file->getAttribute('mimeType'))
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage())
->addHeader('Content-Disposition', 'attachment; filename="' . $file->getAttribute('name', '') . '"')
;
$size = $file->getAttribute('sizeOriginal', 0);
$rangeHeader = $request->getHeader('range');
@@ -1193,7 +1186,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
$end = $request->getRangeEnd();
$unit = $request->getRangeUnit();
if ($end === null) {
if ($end === null || $end - $start > APP_STORAGE_READ_BUFFER) {
$end = min(($start + MAX_OUTPUT_CHUNK_SIZE - 1), ($size - 1));
}
@@ -1208,6 +1201,13 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT);
}
$response
->setContentType($file->getAttribute('mimeType'))
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage())
->addHeader('Content-Disposition', 'attachment; filename="' . $file->getAttribute('name', '') . '"')
;
$source = '';
if (!empty($file->getAttribute('openSSLCipher'))) { // Decrypt
$source = $deviceForFiles->read($path);
@@ -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->getSequence();
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
$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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
}
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
@@ -1345,15 +1345,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
$contentType = $file->getAttribute('mimeType');
}
$response
->setContentType($contentType)
->addHeader('Content-Security-Policy', 'script-src none;')
->addHeader('X-Content-Type-Options', 'nosniff')
->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"')
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage())
;
$size = $file->getAttribute('sizeOriginal', 0);
$rangeHeader = $request->getHeader('range');
@@ -1362,8 +1353,8 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
$end = $request->getRangeEnd();
$unit = $request->getRangeUnit();
if ($end === null) {
$end = min(($start + 2000000 - 1), ($size - 1));
if ($end === null || $end - $start > APP_STORAGE_READ_BUFFER) {
$end = min(($start + APP_STORAGE_READ_BUFFER - 1), ($size - 1));
}
if ($unit != 'bytes' || $start >= $end || $end >= $size) {
@@ -1377,6 +1368,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT);
}
$response
->setContentType($contentType)
->addHeader('Content-Security-Policy', 'script-src none;')
->addHeader('X-Content-Type-Options', 'nosniff')
->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"')
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage())
;
$source = '';
if (!empty($file->getAttribute('openSSLCipher'))) { // Decrypt
$source = $deviceForFiles->read($path);
@@ -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->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
if ($file->isEmpty()) {
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
@@ -1498,14 +1498,6 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
$contentType = $file->getAttribute('mimeType');
}
$response
->setContentType($contentType)
->addHeader('Content-Security-Policy', 'script-src none;')
->addHeader('X-Content-Type-Options', 'nosniff')
->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"')
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage());
$size = $file->getAttribute('sizeOriginal', 0);
$rangeHeader = $request->getHeader('range');
@@ -1514,8 +1506,8 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
$end = $request->getRangeEnd();
$unit = $request->getRangeUnit();
if ($end === null) {
$end = min(($start + 2000000 - 1), ($size - 1));
if ($end === null || $end - $start > APP_STORAGE_READ_BUFFER) {
$end = min(($start + APP_STORAGE_READ_BUFFER - 1), ($size - 1));
}
if ($unit != 'bytes' || $start >= $end || $end >= $size) {
@@ -1529,6 +1521,14 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT);
}
$response
->setContentType($contentType)
->addHeader('Content-Security-Policy', 'script-src none;')
->addHeader('X-Content-Type-Options', 'nosniff')
->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"')
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage());
$source = '';
if (!empty($file->getAttribute('openSSLCipher'))) { // Decrypt
$source = $deviceForFiles->read($path);
@@ -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->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId, $file);
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
} else {
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $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->getSequence(), $fileId);
$deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getSequence(), $fileId));
$deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getInternalId(), $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->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),
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),
];
Authorization::skip(function () use ($dbForProject, $dbForLogs, $bucket, $days, $metrics, &$stats) {
foreach ($metrics as $metric) {
$db = ($metric === str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED))
$db = ($metric === str_replace('{bucketInternalId}', $bucket->getInternalId(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED))
? $dbForLogs
: $dbForProject;
+15 -15
View File
@@ -123,9 +123,9 @@ App::post('/v1/teams')
Permission::delete(Role::team($team->getId(), 'owner')),
],
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'teamId' => $team->getId(),
'teamInternalId' => $team->getSequence(),
'teamInternalId' => $team->getInternalId(),
'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->getSequence()]),
Query::equal('teamInternalId', [$team->getSequence()]),
Query::equal('userInternalId', [$invitee->getInternalId()]),
Query::equal('teamInternalId', [$team->getInternalId()]),
]);
$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->getSequence(),
'userInternalId' => $invitee->getInternalId(),
'teamId' => $team->getId(),
'teamInternalId' => $team->getSequence(),
'teamInternalId' => $team->getInternalId(),
'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->getSequence()]);
$queries[] = Query::equal('teamInternalId', [$team->getInternalId()]);
/**
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
@@ -1092,13 +1092,13 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
collection: 'memberships',
queries: [
Query::contains('roles', ['owner']),
Query::equal('teamInternalId', [$team->getSequence()])
Query::equal('teamInternalId', [$team->getInternalId()])
],
max: 2
);
// Is the role change being requested by the user on their own membership?
$isCurrentUserAnOwner = $user->getSequence() === $membership->getAttribute('userInternalId');
$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'
@@ -1183,7 +1183,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
throw new Exception(Exception::TEAM_NOT_FOUND);
}
if ($membership->getAttribute('teamInternalId') !== $team->getSequence()) {
if ($membership->getAttribute('teamInternalId') !== $team->getInternalId()) {
throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH);
}
@@ -1200,7 +1200,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
$user->setAttributes($dbForProject->getDocument('users', $userId)->getArrayCopy()); // Get user
}
if ($membership->getAttribute('userInternalId') !== $user->getSequence()) {
if ($membership->getAttribute('userInternalId') !== $user->getInternalId()) {
throw new Exception(Exception::TEAM_INVITE_MISMATCH, 'Invite does not belong to current user (' . $user->getAttribute('email') . ')');
}
@@ -1232,7 +1232,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
Permission::delete(Role::user($user->getId())),
],
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'provider' => Auth::SESSION_PROVIDER_EMAIL,
'providerUid' => $user->getAttribute('email'),
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
@@ -1343,7 +1343,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
throw new Exception(Exception::TEAM_NOT_FOUND);
}
if ($membership->getAttribute('teamInternalId') !== $team->getSequence()) {
if ($membership->getAttribute('teamInternalId') !== $team->getInternalId()) {
throw new Exception(Exception::TEAM_MEMBERSHIP_MISMATCH);
}
@@ -1354,7 +1354,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
collection: 'memberships',
queries: [
Query::contains('roles', ['owner']),
Query::equal('teamInternalId', [$team->getSequence()])
Query::equal('teamInternalId', [$team->getInternalId()])
],
max: 2
);
@@ -1362,7 +1362,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
// 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->getSequence();
$membership->getAttribute('userInternalId') === $user->getInternalId();
if ($ownersCount === 1 && $isSelfOwner) {
/* Prevent removal if the user is the only owner. */
+16 -16
View File
@@ -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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'providerInternalId' => $provider->isEmpty() ? null : $provider->getInternalId(),
'providerType' => $providerType,
'userId' => $userId,
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'identifier' => $identifier,
'name' => ($name !== '') ? $name : null,
]));
@@ -846,7 +846,7 @@ App::get('/v1/users/:userId/memberships')
}
// Set internal queries
$queries[] = Query::equal('userInternalId', [$user->getSequence()]);
$queries[] = Query::equal('userInternalId', [$user->getInternalId()]);
$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->getSequence(), $queries);
$logs = $audit->getLogsByUser($user->getInternalId(), $queries);
$output = [];
@@ -957,7 +957,7 @@ App::get('/v1/users/:userId/logs')
}
$response->dynamic(new Document([
'total' => $audit->countLogsByUser($user->getSequence(), $queries),
'total' => $audit->countLogsByUser($user->getInternalId(), $queries),
'logs' => $output,
]), Response::MODEL_LOG_LIST);
});
@@ -980,7 +980,7 @@ App::get('/v1/users/:userId/targets')
]
))
->param('userId', '', new UID(), 'User ID.')
->param('queries', [], new Targets(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Targets::ALLOWED_ATTRIBUTES), true)
->param('queries', [], new Targets(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Users::ALLOWED_ATTRIBUTES), true)
->inject('response')
->inject('dbForProject')
->action(function (string $userId, array $queries, Response $response, Database $dbForProject) {
@@ -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->getSequence()),
Query::notEqual('userInternalId', $user->getInternalId()),
]);
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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'providerType' => 'sms',
'identifier' => $number,
]));
@@ -1711,7 +1711,7 @@ App::patch('/v1/users/:userId/targets/:targetId')
$target
->setAttribute('providerId', $provider->getId())
->setAttribute('providerInternalId', $provider->getSequence());
->setAttribute('providerInternalId', $provider->getInternalId());
}
if ($name) {
@@ -2051,7 +2051,7 @@ App::post('/v1/users/:userId/sessions')
[
'$id' => ID::unique(),
'userId' => $user->getId(),
'userInternalId' => $user->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence(),
'userInternalId' => $user->getInternalId(),
'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->getSequence()]));
DeleteTargets::delete($dbForProject, Query::equal('userInternalId', [$user->getSequence()]));
DeleteIdentities::delete($dbForProject, Query::equal('userInternalId', [$user->getInternalId()]));
DeleteTargets::delete($dbForProject, Query::equal('userInternalId', [$user->getInternalId()]));
$queueForDeletes
->setType(DELETE_TYPE_DOCUMENT)
+29 -33
View File
@@ -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->getSequence();
$resourceInternalId = $resource->getInternalId();
$deploymentId = ID::unique();
$repositoryId = $repository->getId();
$repositoryInternalId = $repository->getSequence();
$repositoryInternalId = $repository->getInternalId();
$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->getSequence(),
'projectInternalId' => $project->getInternalId(),
'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->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->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->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $resourceId,
'deploymentResourceInternalId' => $resourceInternalId,
@@ -306,12 +306,12 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $resourceId,
'deploymentResourceInternalId' => $resourceInternalId,
@@ -337,12 +337,12 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $resourceId,
'deploymentResourceInternalId' => $resourceInternalId,
@@ -363,7 +363,6 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
if (!empty($providerCommitHash) && $resource->getAttribute('providerSilentMode', false) === false) {
$resourceName = $resource->getAttribute('name');
$projectName = $project->getAttribute('name');
$region = $project->getAttribute('region', 'default');
$name = "{$resourceName} ({$projectName})";
$message = 'Starting...';
@@ -378,7 +377,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
}
$owner = $github->getOwnerName($providerInstallationId);
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/$resourceCollection/$resourceType-$resourceId";
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/$resourceCollection/$resourceType-$resourceId";
$github->updateCommitStatus($repositoryName, $providerCommitHash, $owner, 'pending', $message, $providerTargetUrl, $name);
}
@@ -477,6 +476,16 @@ App::get('/v1/vcs/github/callback')
$state = \json_decode($state, true);
$projectId = $state['projectId'] ?? '';
$defaultState = [
'success' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/settings/git-installations",
'failure' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/settings/git-installations",
];
$state = \array_merge($defaultState, $state ?? []);
$redirectSuccess = $state['success'] ?? '';
$redirectFailure = $state['failure'] ?? '';
$project = $dbForPlatform->getDocument('projects', $projectId);
if ($project->isEmpty()) {
@@ -493,18 +502,6 @@ App::get('/v1/vcs/github/callback')
throw new Exception(Exception::PROJECT_NOT_FOUND, $error);
}
$region = $project->getAttribute('region', 'default');
$defaultState = [
'success' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/settings/git-installations",
'failure' => $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$region-$projectId/settings/git-installations",
];
$state = \array_merge($defaultState, $state ?? []);
$redirectSuccess = $state['success'] ?? '';
$redirectFailure = $state['failure'] ?? '';
// Create / Update installation
if (!empty($providerInstallationId)) {
$privateKey = System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');
@@ -512,7 +509,7 @@ App::get('/v1/vcs/github/callback')
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
$owner = $github->getOwnerName($providerInstallationId) ?? '';
$projectInternalId = $project->getSequence();
$projectInternalId = $project->getInternalId();
$installation = $dbForPlatform->findOne('installations', [
Query::equal('providerInstallationId', [$providerInstallationId]),
@@ -608,12 +605,11 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro
->param('installationId', '', new Text(256), 'Installation Id')
->param('providerRepositoryId', '', new Text(256), 'Repository Id')
->param('providerRootDirectory', '', new Text(256, 0), 'Path to get contents of nested directory', true)
->param('providerReference', '', new Text(256, 0), 'Git reference (branch, tag, commit) to get contents from', true)
->inject('gitHub')
->inject('response')
->inject('project')
->inject('dbForPlatform')
->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, string $providerReference, GitHub $github, Response $response, Document $project, Database $dbForPlatform) {
->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, GitHub $github, Response $response, Document $project, Database $dbForPlatform) {
$installation = $dbForPlatform->getDocument('installations', $installationId);
if ($installation->isEmpty()) {
@@ -635,7 +631,7 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro
throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND);
}
$contents = $github->listRepositoryContents($owner, $repositoryName, $providerRootDirectory, $providerReference);
$contents = $github->listRepositoryContents($owner, $repositoryName, $providerRootDirectory);
$vcsContents = [];
foreach ($contents as $content) {
@@ -1009,7 +1005,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->getSequence()]),
Query::equal('userInternalId', [$user->getInternalId()]),
]);
if ($identity->isEmpty()) {
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
@@ -1257,7 +1253,7 @@ App::post('/v1/vcs/github/events')
foreach ($installations as $installation) {
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
Query::equal('installationInternalId', [$installation->getSequence()]),
Query::equal('installationInternalId', [$installation->getInternalId()]),
Query::limit(1000)
]));
@@ -1360,7 +1356,7 @@ App::get('/v1/vcs/installations')
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries[] = Query::equal('projectInternalId', [$project->getSequence()]);
$queries[] = Query::equal('projectInternalId', [$project->getInternalId()]);
if (!empty($search)) {
$queries[] = Query::search('search', $search);
@@ -1433,7 +1429,7 @@ App::get('/v1/vcs/installations/:installationId')
throw new Exception(Exception::INSTALLATION_NOT_FOUND);
}
if ($installation->getAttribute('projectInternalId') !== $project->getSequence()) {
if ($installation->getAttribute('projectInternalId') !== $project->getInternalId()) {
throw new Exception(Exception::INSTALLATION_NOT_FOUND);
}
@@ -1516,7 +1512,7 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor
}
$repository = Authorization::skip(fn () => $dbForPlatform->getDocument('repositories', $repositoryId, [
Query::equal('projectInternalId', [$project->getSequence()])
Query::equal('projectInternalId', [$project->getInternalId()])
]));
if ($repository->isEmpty()) {
+42 -26
View File
@@ -107,6 +107,7 @@ 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)
@@ -126,6 +127,7 @@ 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'] ?? '/');
@@ -136,6 +138,7 @@ 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) {
@@ -144,6 +147,7 @@ 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);
@@ -186,7 +190,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$resourceId = $rule->getAttribute('deploymentResourceId', '');
$type = ($resourceType === 'site') ? 'sites' : 'functions';
$exception = new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, view: $errorView);
$exception->addCTA('View deployments', $url . '/console/project-' . $project->getAttribute('region', 'default') . '-' . $projectId . '/' . $type . '/' . $resourceType . '-' . $resourceId);
$exception->addCTA('View deployments', $url . '/console/project-' . $projectId . '/' . $type . '/' . $resourceType . '-' . $resourceId);
throw $exception;
}
@@ -194,6 +198,7 @@ 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'] ?? '/');
@@ -275,6 +280,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
return true;
}
}
// @luke implement END
$body = $swooleRequest->getContent() ?? '';
$method = $swooleRequest->server['request_method'];
@@ -289,9 +295,11 @@ 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'),
@@ -316,25 +324,26 @@ 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');
$region = $project->getAttribute('region', 'default');
switch ($status) {
case 'failed':
$exception = new AppwriteException(AppwriteException::BUILD_FAILED, view: $errorView);
$ctaUrl = '/console/project-' . $region . '-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$ctaUrl = '/console/project-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$exception->addCTA('View logs', $url . $ctaUrl);
break;
case 'canceled':
$exception = new AppwriteException(AppwriteException::BUILD_CANCELED, view: $errorView);
$ctaUrl = '/console/project-' . $region . '-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments';
$ctaUrl = '/console/project-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments';
$exception->addCTA('View deployments', $url . $ctaUrl);
break;
default:
$exception = new AppwriteException(AppwriteException::BUILD_NOT_READY, view: $errorView);
$ctaUrl = '/console/project-' . $region . '-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$ctaUrl = '/console/project-' . $project->getId() . '/sites/site-' . $resource->getId() . '/deployments/deployment-' . $deployment->getId();
$exception->addCTA('Reload', '/');
$exception->addCTA('View logs', $url . $ctaUrl);
break;
@@ -346,7 +355,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$permissions = $resource->getAttribute('execute');
if (!(\in_array('any', $permissions)) && !(\in_array('guests', $permissions))) {
$exception = new AppwriteException(AppwriteException::FUNCTION_EXECUTE_PERMISSION_MISSING, view: $errorView);
$exception->addCTA('View settings', $url . '/console/project-' . $project->getAttribute('region', 'default') . '-' . $project->getId() . '/functions/function-' . $resource->getId() . '/settings');
$exception->addCTA('View settings', $url . '/console/project-' . $project->getId() . '/functions/function-' . $resource->getId() . '/settings');
throw $exception;
}
}
@@ -392,9 +401,9 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$execution = new Document([
'$id' => $executionId,
'$permissions' => [],
'resourceInternalId' => $resource->getSequence(),
'resourceInternalId' => $resource->getInternalId(),
'resourceId' => $resource->getId(),
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
'responseStatusCode' => 0,
'responseHeaders' => [],
@@ -429,6 +438,7 @@ 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'] ?? '',
@@ -437,6 +447,7 @@ 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) {
@@ -508,30 +519,33 @@ 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' => '',
};
$source = $deployment->getAttribute('buildPath', '');
$extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz';
// @luke implement END
$startCommand = $runtime['startCommand'];
if ($type === 'site') {
if ($type === 'function') {
$runtimeEntrypoint = match ($version) {
'v2' => '',
default => 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $runtime['startCommand'] . '"'
};
} elseif ($type === 'site') {
$frameworks = Config::getParam('frameworks', []);
$framework = $frameworks[$resource->getAttribute('framework', '')] ?? null;
$startCommand = $runtime['startCommand'];
if (!is_null($framework)) {
$adapter = ($framework['adapters'] ?? [])[$deployment->getAttribute('adapter', '')] ?? null;
if (!is_null($adapter) && isset($adapter['startCommand'])) {
$startCommand = $adapter['startCommand'];
}
}
}
$runtimeEntrypoint = match ($version) {
'v2' => '',
default => "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$startCommand\"",
};
$runtimeEntrypoint = 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $startCommand . '"';
}
$entrypoint = match ($type) {
'function' => $deployment->getAttribute('entrypoint', ''),
@@ -545,7 +559,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
variables: $vars,
timeout: $resource->getAttribute('timeout', 30),
image: $runtime['image'],
source: $source,
source: $deployment->getAttribute('buildPath', ''),
entrypoint: $entrypoint,
version: $version,
path: $path,
@@ -587,6 +601,7 @@ 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
@@ -603,6 +618,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
}
}
// @luke implement END
$headersFiltered = [];
foreach ($executionResponse['headers'] as $key => $value) {
@@ -692,11 +708,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->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS);
$metricTypeIdExecutions = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE);
$metricTypeIdExecutionsCompute = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], 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->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
$metricTypeIdExecutionsMBSeconds = str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS);
if ($deployment->getAttribute('resourceType') === 'sites') {
$queueForStatsUsage
->disableMetric(METRIC_NETWORK_REQUESTS)
@@ -719,9 +735,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->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())
->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())
;
}
@@ -908,7 +924,7 @@ App::init()
'type' => 'api',
'status' => 'verifying',
'projectId' => $console->getId(),
'projectInternalId' => $console->getSequence(),
'projectInternalId' => $console->getInternalId(),
'search' => implode(' ', [$ruleId, $domain->get()]),
'owner' => $owner,
'region' => $console->getAttribute('region')
@@ -958,7 +974,7 @@ App::init()
)[0] ?? new Document();
}
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getSequence()) {
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getInternalId()) {
$refDomainOrigin = $origin;
}
}
+2 -2
View File
@@ -185,7 +185,7 @@ App::post('/v1/mock/api-key-unprefixed')
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'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->getSequence();
$projectInternalId = $project->getInternalId();
$teamId = $project->getAttribute('teamId', '');
+4 -4
View File
@@ -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->getSequence();
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getInternalId();
$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->getSequence(), $fileId);
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId);
} else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId));
}
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getInternalId()) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
+2 -2
View File
@@ -309,7 +309,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
'orders' => $index['orders'],
]), $files['indexes']);
$dbForPlatform->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes);
$dbForPlatform->createCollection('bucket_' . $bucket->getInternalId(), $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->getSequence(), $attributes, $indexes));
Authorization::skip(fn () => $dbForPlatform->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes));
}
});
-1
View File
@@ -51,7 +51,6 @@ 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';
+21 -30
View File
@@ -71,27 +71,18 @@ Database::addFilter(
},
function (mixed $value, Document $document, Database $database) {
$attributes = $database->find('attributes', [
Query::equal('collectionInternalId', [$document->getSequence()]),
Query::equal('collectionInternalId', [$document->getInternalId()]),
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
Query::limit($database->getLimitForAttributes()),
]);
foreach ($attributes as $attribute) {
$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;
if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) {
$options = $attribute->getAttribute('options');
foreach ($options as $key => $value) {
$attribute->setAttribute($key, $value);
}
$attribute->removeAttribute('options');
}
}
@@ -107,7 +98,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return $database
->find('indexes', [
Query::equal('collectionInternalId', [$document->getSequence()]),
Query::equal('collectionInternalId', [$document->getInternalId()]),
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
Query::limit($database->getLimitForIndexes()),
]);
@@ -122,7 +113,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return $database
->find('platforms', [
Query::equal('projectInternalId', [$document->getSequence()]),
Query::equal('projectInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]);
}
@@ -136,7 +127,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return $database
->find('keys', [
Query::equal('projectInternalId', [$document->getSequence()]),
Query::equal('projectInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]);
}
@@ -150,7 +141,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return $database
->find('devKeys', [
Query::equal('projectInternalId', [$document->getSequence()]),
Query::equal('projectInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]);
}
@@ -164,7 +155,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return $database
->find('webhooks', [
Query::equal('projectInternalId', [$document->getSequence()]),
Query::equal('projectInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]);
}
@@ -177,7 +168,7 @@ Database::addFilter(
},
function (mixed $value, Document $document, Database $database) {
return Authorization::skip(fn () => $database->find('sessions', [
Query::equal('userInternalId', [$document->getSequence()]),
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
@@ -191,7 +182,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return Authorization::skip(fn () => $database
->find('tokens', [
Query::equal('userInternalId', [$document->getSequence()]),
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
@@ -205,7 +196,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return Authorization::skip(fn () => $database
->find('challenges', [
Query::equal('userInternalId', [$document->getSequence()]),
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
@@ -219,7 +210,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return Authorization::skip(fn () => $database
->find('authenticators', [
Query::equal('userInternalId', [$document->getSequence()]),
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
@@ -233,7 +224,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return Authorization::skip(fn () => $database
->find('memberships', [
Query::equal('userInternalId', [$document->getSequence()]),
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY),
]));
}
@@ -247,7 +238,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return $database
->find('variables', [
Query::equal('resourceInternalId', [$document->getSequence()]),
Query::equal('resourceInternalId', [$document->getInternalId()]),
Query::equal('resourceType', ['function', 'site']),
Query::limit(APP_LIMIT_SUBQUERY),
]);
@@ -325,7 +316,7 @@ Database::addFilter(
function (mixed $value, Document $document, Database $database) {
return Authorization::skip(fn () => $database
->find('targets', [
Query::equal('userInternalId', [$document->getSequence()]),
Query::equal('userInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBQUERY)
]));
}
@@ -340,13 +331,13 @@ Database::addFilter(
$targetIds = Authorization::skip(fn () => \array_map(
fn ($document) => $document->getAttribute('targetInternalId'),
$database->find('subscribers', [
Query::equal('topicInternalId', [$document->getSequence()]),
Query::equal('topicInternalId', [$document->getInternalId()]),
Query::limit(APP_LIMIT_SUBSCRIBERS_SUBQUERY)
])
));
if (\count($targetIds) > 0) {
return $database->skipValidation(fn () => $database->find('targets', [
Query::equal('$sequence', $targetIds)
Query::equal('$internalId', $targetIds)
]));
}
return [];
+12 -12
View File
@@ -348,13 +348,13 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
return $database;
@@ -401,13 +401,13 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
});
@@ -431,7 +431,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((int)$project->getSequence());
$database->setTenant($project->getInternalId());
return $database;
}
@@ -446,7 +446,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
// set tenant
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
$database->setTenant((int)$project->getSequence());
$database->setTenant($project->getInternalId());
}
return $database;
@@ -839,7 +839,7 @@ App::setResource('team', function (Document $project, Database $dbForPlatform, A
$team = Authorization::skip(function () use ($dbForPlatform, $teamInternalId) {
return $dbForPlatform->findOne('teams', [
Query::equal('$sequence', [$teamInternalId]),
Query::equal('$internalId', [$teamInternalId]),
]);
});
@@ -880,7 +880,7 @@ App::setResource('apiKey', function (Request $request, Document $project): ?Key
return Key::decode($project, $key);
}, ['request', 'project']);
App::setResource('executor', fn () => new Executor());
App::setResource('executor', fn () => new Executor(fn (string $projectId, string $deploymentId) => System::getEnv('_APP_EXECUTOR_HOST')));
App::setResource('resourceToken', function ($project, $dbForProject, $request) {
$tokenJWT = $request->getParam('token');
@@ -918,10 +918,10 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) {
return match ($token->getAttribute('resourceType')) {
TOKENS_RESOURCE_TYPE_FILES => (function () use ($token, $dbForProject) {
$sequences = explode(':', $token->getAttribute('resourceInternalId'));
$internalIds = explode(':', $token->getAttribute('resourceInternalId'));
$ids = explode(':', $token->getAttribute('resourceId'));
if (count($sequences) !== 2 || count($ids) !== 2) {
if (count($internalIds) !== 2 || count($ids) !== 2) {
return new Document([]);
}
@@ -934,8 +934,8 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) {
return new Document([
'bucketId' => $ids[0],
'fileId' => $ids[1],
'bucketInternalId' => $sequences[0],
'fileInternalId' => $sequences[1],
'bucketInternalId' => $internalIds[0],
'fileInternalId' => $internalIds[1],
]);
})(),
+5 -5
View File
@@ -79,8 +79,8 @@ if (!function_exists('getProjectDB')) {
static $databases = [];
if (isset($databases[$project->getSequence()])) {
return $databases[$project->getSequence()];
if (isset($databases[$project->getInternalId()])) {
return $databases[$project->getInternalId()];
}
/** @var Group $pools */
@@ -105,20 +105,20 @@ if (!function_exists('getProjectDB')) {
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
$database
->setMetadata('host', \gethostname())
->setMetadata('project', $project->getId());
return $databases[$project->getSequence()] = $database;
return $databases[$project->getInternalId()] = $database;
}
}
+1 -1
View File
@@ -841,7 +841,7 @@ $image = $this->getParam('image', '');
- _APP_DB_PASS
appwrite-assistant:
image: appwrite/assistant:0.8.3
image: appwrite/assistant:0.4.0
container_name: appwrite-assistant
<<: *x-logging
restart: unless-stopped
+9 -9
View File
@@ -94,13 +94,13 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register,
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
@@ -131,13 +131,13 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
return $database;
@@ -153,13 +153,13 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
if (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int)$project->getSequence())
->setTenant($project->getInternalId())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
->setNamespace('_' . $project->getInternalId());
}
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
@@ -172,7 +172,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((int)$project->getSequence());
$database->setTenant($project->getInternalId());
return $database;
}
@@ -187,7 +187,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
// set tenant
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
$database->setTenant((int)$project->getSequence());
$database->setTenant($project->getInternalId());
}
return $database;
@@ -402,7 +402,7 @@ Server::setResource('logError', function (Registry $register, Document $project)
};
}, ['register', 'project']);
Server::setResource('executor', fn () => new Executor());
Server::setResource('executor', fn () => new Executor(fn (string $projectId, string $deploymentId) => System::getEnv('_APP_EXECUTOR_HOST')));
$pools = $register->get('pools');
$platform = new Appwrite();
+3 -3
View File
@@ -52,9 +52,9 @@
"utopia-php/cache": "0.13.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.71.*",
"utopia-php/detector": "0.1.*",
"utopia-php/domains": "0.8.*",
"utopia-php/database": "0.69.*",
"utopia-php/domains": "0.8.0",
"utopia-php/dsn": "0.2.1",
"utopia-php/framework": "0.33.*",
"utopia-php/fetch": "0.4.*",
@@ -62,7 +62,7 @@
"utopia-php/locale": "0.4.*",
"utopia-php/logger": "0.6.*",
"utopia-php/messaging": "0.18.*",
"utopia-php/migration": "0.10.*",
"utopia-php/migration": "0.9.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.7.*",
"utopia-php/pools": "0.8.*",
Generated
+39 -38
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1557e469b3074a6478a0b2fd522e1a2a",
"content-hash": "3230eea9e592f0b712e78c1ef5f5e244",
"packages": [
{
"name": "adhocore/jwt",
@@ -1874,16 +1874,16 @@
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.44",
"version": "3.0.43",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "1d0b5e7e1434678411787c5a0535e68907cf82d9"
"reference": "709ec107af3cb2f385b9617be72af8cf62441d02"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/1d0b5e7e1434678411787c5a0535e68907cf82d9",
"reference": "1d0b5e7e1434678411787c5a0535e68907cf82d9",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/709ec107af3cb2f385b9617be72af8cf62441d02",
"reference": "709ec107af3cb2f385b9617be72af8cf62441d02",
"shasum": ""
},
"require": {
@@ -1964,7 +1964,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.44"
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.43"
},
"funding": [
{
@@ -1980,7 +1980,7 @@
"type": "tidelift"
}
],
"time": "2025-06-15T09:59:26+00:00"
"time": "2024-12-14T21:12:59+00:00"
},
{
"name": "psr/container",
@@ -3490,16 +3490,16 @@
},
{
"name": "utopia-php/database",
"version": "0.71.6",
"version": "0.69.7",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "2bd87acc40af087fc0fdcccc47c43141dff0be5c"
"reference": "3db51ec544b3f287511209e34bab3f5ec85fa56e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/2bd87acc40af087fc0fdcccc47c43141dff0be5c",
"reference": "2bd87acc40af087fc0fdcccc47c43141dff0be5c",
"url": "https://api.github.com/repos/utopia-php/database/zipball/3db51ec544b3f287511209e34bab3f5ec85fa56e",
"reference": "3db51ec544b3f287511209e34bab3f5ec85fa56e",
"shasum": ""
},
"require": {
@@ -3540,9 +3540,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.71.6"
"source": "https://github.com/utopia-php/database/tree/0.69.7"
},
"time": "2025-06-16T16:48:37+00:00"
"time": "2025-05-30T14:41:25+00:00"
},
{
"name": "utopia-php/detector",
@@ -3990,16 +3990,16 @@
},
{
"name": "utopia-php/migration",
"version": "0.10.1",
"version": "0.9.3",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/migration.git",
"reference": "ea1c585df7ec5f346f061a11581fc9a91679966f"
"reference": "e518d39eb550fde36bc5cf06c9bd7b2faf5dbedd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/ea1c585df7ec5f346f061a11581fc9a91679966f",
"reference": "ea1c585df7ec5f346f061a11581fc9a91679966f",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/e518d39eb550fde36bc5cf06c9bd7b2faf5dbedd",
"reference": "e518d39eb550fde36bc5cf06c9bd7b2faf5dbedd",
"shasum": ""
},
"require": {
@@ -4040,9 +4040,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/0.10.1"
"source": "https://github.com/utopia-php/migration/tree/0.9.3"
},
"time": "2025-05-26T15:29:19+00:00"
"time": "2025-05-01T05:41:26+00:00"
},
{
"name": "utopia-php/orchestration",
@@ -4584,16 +4584,16 @@
},
{
"name": "utopia-php/vcs",
"version": "0.10.5",
"version": "0.10.4",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/vcs.git",
"reference": "b358439dc387f6097019eb83ebb9fc258fe9da05"
"reference": "f635b368909eb3c3fe57344fe43525e74e8fdc03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/b358439dc387f6097019eb83ebb9fc258fe9da05",
"reference": "b358439dc387f6097019eb83ebb9fc258fe9da05",
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/f635b368909eb3c3fe57344fe43525e74e8fdc03",
"reference": "f635b368909eb3c3fe57344fe43525e74e8fdc03",
"shasum": ""
},
"require": {
@@ -4627,9 +4627,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/vcs/issues",
"source": "https://github.com/utopia-php/vcs/tree/0.10.5"
"source": "https://github.com/utopia-php/vcs/tree/0.10.4"
},
"time": "2025-06-10T15:01:16+00:00"
"time": "2025-06-02T09:18:36+00:00"
},
{
"name": "utopia-php/websocket",
@@ -4807,16 +4807,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.41.7",
"version": "0.41.1",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "d8c7bb26ea32ab378faf4e0dfa62fd15fe37c57b"
"reference": "6d9318abf4542a757c87abf056557d6afa1dc06b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d8c7bb26ea32ab378faf4e0dfa62fd15fe37c57b",
"reference": "d8c7bb26ea32ab378faf4e0dfa62fd15fe37c57b",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6d9318abf4542a757c87abf056557d6afa1dc06b",
"reference": "6d9318abf4542a757c87abf056557d6afa1dc06b",
"shasum": ""
},
"require": {
@@ -4852,9 +4852,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.7"
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.1"
},
"time": "2025-06-13T17:05:57+00:00"
"time": "2025-06-01T04:20:04+00:00"
},
{
"name": "doctrine/annotations",
@@ -5147,16 +5147,16 @@
},
{
"name": "matthiasmullie/minify",
"version": "1.3.74",
"version": "1.3.73",
"source": {
"type": "git",
"url": "https://github.com/matthiasmullie/minify.git",
"reference": "a2593286a4135d03c6a6a9e9aeded5d41e931ce4"
"reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/a2593286a4135d03c6a6a9e9aeded5d41e931ce4",
"reference": "a2593286a4135d03c6a6a9e9aeded5d41e931ce4",
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/cb7a9297b4ab070909cefade30ee95054d4ae87a",
"reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a",
"shasum": ""
},
"require": {
@@ -5167,7 +5167,8 @@
"require-dev": {
"friendsofphp/php-cs-fixer": ">=2.0",
"matthiasmullie/scrapbook": ">=1.3",
"phpunit/phpunit": ">=4.8"
"phpunit/phpunit": ">=4.8",
"squizlabs/php_codesniffer": ">=3.0"
},
"suggest": {
"psr/cache-implementation": "Cache implementation to use with Minify::cache"
@@ -5205,7 +5206,7 @@
],
"support": {
"issues": "https://github.com/matthiasmullie/minify/issues",
"source": "https://github.com/matthiasmullie/minify/tree/1.3.74"
"source": "https://github.com/matthiasmullie/minify/tree/1.3.73"
},
"funding": [
{
@@ -5213,7 +5214,7 @@
"type": "github"
}
],
"time": "2025-06-12T08:06:04+00:00"
"time": "2024-03-15T10:27:10+00:00"
},
{
"name": "matthiasmullie/path-converter",
+2 -2
View File
@@ -213,7 +213,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:6.0.41
image: appwrite/console:6.0.32
restart: unless-stopped
networks:
- appwrite
@@ -934,7 +934,7 @@ services:
appwrite-assistant:
container_name: appwrite-assistant
image: appwrite/assistant:0.8.3
image: appwrite/assistant:0.7.0
networks:
- appwrite
environment:
@@ -1,6 +1,4 @@
appwrite proxy createRedirectRule \
--domain '' \
--url https://example.com \
--statusCode 301 \
--resourceId <RESOURCE_ID> \
--resourceType site
--statusCode 301
@@ -2,4 +2,3 @@ appwrite vcs getRepositoryContents \
--installationId <INSTALLATION_ID> \
--providerRepositoryId <PROVIDER_REPOSITORY_ID> \
@@ -1,3 +1 @@
**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.
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.
@@ -1 +0,0 @@
Decrement a specific attribute of a document by a given value.
@@ -1,3 +1 @@
**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.
Bulk delete documents using queries, if no queries are passed then all documents are deleted.
@@ -1 +0,0 @@
Increment a specific attribute of a document by a given value.
@@ -1,3 +1 @@
**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.
Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.
@@ -1,3 +1 @@
**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.
Create or update a 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.
@@ -1,3 +1 @@
**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.
Create or update 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.
Create or update 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.
@@ -1 +1 @@
Get a list of files and directories from a GitHub repository connected to your project. This endpoint returns the contents of a specified repository path, including file names, sizes, and whether each item is a file or directory. The GitHub installation must be properly configured and the repository must be accessible through your installation for this endpoint to work.
Get a list of files and directories from a GitHub repository connected to your project. This endpoint returns the contents of a specified repository path, including file names, sizes, and whether each item is a file or directory. The GitHub installation must be properly configured and the repository must be accessible through your installation for this endpoint to work.
+2 -2
View File
@@ -27,7 +27,7 @@ class Targets
$database->deleteDocuments(
'subscribers',
[
Query::equal('targetInternalId', [$target->getSequence()]),
Query::equal('targetInternalId', [$target->getInternalId()]),
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->getSequence() === $topicInternalId) {
if (!$topic->isEmpty() && $topic->getInternalId() === $topicInternalId) {
$totalAttribute = match ($target->getAttribute('providerType')) {
MESSAGE_TYPE_EMAIL => 'emailTotal',
MESSAGE_TYPE_SMS => 'smsTotal',
+1 -1
View File
@@ -320,7 +320,7 @@ class Event
if ($this->project) {
$trimmed['project'] = new Document([
'$id' => $this->project->getId(),
'$sequence' => $this->project->getSequence(),
'$internalId' => $this->project->getInternalId(),
'database' => $this->project->getAttribute('database')
]);
}
+6 -6
View File
@@ -157,7 +157,7 @@ abstract class Migration
*/
public function forEachDocument(callable $callback): void
{
$projectInternalId = $this->project->getSequence();
$projectInternalId = $this->project->getInternalId();
$collections = match ($projectInternalId) {
'console' => $this->collections['console'],
@@ -210,7 +210,7 @@ abstract class Migration
{
$name ??= $id;
$collectionType = match ($this->project->getSequence()) {
$collectionType = match ($this->project->getInternalId()) {
'console' => 'console',
default => 'projects',
};
@@ -261,7 +261,7 @@ abstract class Migration
): void {
$from ??= $collectionId;
$collectionType = match ($this->project->getSequence()) {
$collectionType = match ($this->project->getInternalId()) {
'console' => 'console',
default => 'projects',
};
@@ -326,7 +326,7 @@ abstract class Migration
): void {
$from ??= $collectionId;
$collectionType = match ($this->project->getSequence()) {
$collectionType = match ($this->project->getInternalId()) {
'console' => 'console',
default => 'projects',
};
@@ -384,7 +384,7 @@ abstract class Migration
{
$from ??= $collectionId;
$collectionType = match ($this->project->getSequence()) {
$collectionType = match ($this->project->getInternalId()) {
'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->getSequence()}_{$collection}` MODIFY `$attribute` $type;");
$stmt = $this->pdo->prepare("ALTER TABLE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$collection}` MODIFY `$attribute` $type;");
try {
$stmt->execute();
+15 -15
View File
@@ -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->getSequence()}";
$bucketTable = "bucket_{$bucket->getInternalId()}";
$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->getSequence()}";
$databaseTable = "database_{$database->getInternalId()}";
$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->getSequence()}";
$collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}";
$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->getSequence()}", 'permission');
$this->dbForProject->deleteAttribute("database_{$database->getInternalId()}", '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->getSequence()}_{$table}_perms` WHERE _type = 'write'")->execute();
$this->pdo->prepare("DELETE FROM `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$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->getSequence()}_{$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->getInternalId()}_{$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->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();
$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();
$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->getSequence()}_{$table}` MODIFY {$attribute} DATETIME(3)")->execute();
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$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->getSequence()}_{$table}` ADD `_permissions` MEDIUMTEXT DEFAULT NULL")->execute();
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$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->getSequence()}_{$table}_perms` WHERE _document = '{$document->getId()}'");
$query = $this->pdo->prepare("SELECT * FROM `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_{$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->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
switch ($id) {
case '_metadata':
@@ -746,7 +746,7 @@ class V15 extends Migration
Permission::delete(Role::any()),
],
'functionId' => $function->getId(),
'functionInternalId' => $function->getSequence(),
'functionInternalId' => $function->getInternalId(),
'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->getSequence()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
} catch (\Throwable $th) {
Console::warning("Migrating steps from {$this->dbForProject->getDatabase()}`.`_{$this->project->getSequence()}_stats:" . $th->getMessage());
Console::warning("Migrating steps from {$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}_stats:" . $th->getMessage());
}
}
+1 -1
View File
@@ -45,7 +45,7 @@ class V16 extends Migration
Console::log("Migrating Collection \"{$id}\"");
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
switch ($id) {
case 'sessions':
+2 -2
View File
@@ -44,7 +44,7 @@ class V17 extends Migration
protected function migrateBuckets(): void
{
foreach ($this->documentsIterator('buckets') as $bucket) {
$id = "bucket_{$bucket->getSequence()}";
$id = "bucket_{$bucket->getInternalId()}";
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->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
switch ($id) {
case 'builds':
+8 -8
View File
@@ -26,7 +26,7 @@ class V18 extends Migration
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
$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->getSequence()}";
$databaseTable = "database_{$database->getInternalId()}";
Console::info("Migrating Collections of {$database->getId()} ({$database->getAttribute('name')})");
foreach ($this->documentsIterator($databaseTable) as $collection) {
$collectionTable = "{$databaseTable}_collection_{$collection->getSequence()}";
$collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}";
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->getSequence()}";
$internalBucketId = "bucket_{$this->project->getInternalId()}";
$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;
}
$sequence = $user->getSequence();
$document->setAttribute('userId', $sequence);
$internalId = $user->getInternalId();
$document->setAttribute('userId', $internalId);
$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->getSequence()}__metadata` ADD COLUMN IF NOT EXISTS documentSecurity TINYINT(1);")->execute();
$this->pdo->prepare("ALTER TABLE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}__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->getSequence()}__metadata` SET documentSecurity = 1 WHERE documentSecurity IS NULL")->execute();
$this->pdo->prepare("UPDATE `{$this->dbForProject->getDatabase()}`.`_{$this->project->getInternalId()}__metadata` SET documentSecurity = 1 WHERE documentSecurity IS NULL")->execute();
} catch (\Throwable $th) {
Console::warning($th->getMessage());
}
+12 -12
View File
@@ -28,7 +28,7 @@ class V19 extends Migration
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
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->getSequence()}";
$id = "bucket_{$bucket->getInternalId()}";
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->getSequence();
$internalProjectId = $this->project->getInternalId();
$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->getSequence());
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
$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->getSequence());
$document->setAttribute('resourceInternalId', $function->getInternalId());
$buildId = $document->getAttribute('buildId');
if (!empty($buildId)) {
$build = $this->dbForProject->getDocument('builds', $buildId);
$document->setAttribute('buildInternalId', $build->getSequence());
$document->setAttribute('buildInternalId', $build->getInternalId());
}
$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->getSequence());
$document->setAttribute('functionInternalId', $function->getInternalId());
$deploymentId = $document->getAttribute('deploymentId');
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
$document->setAttribute('deploymentInternalId', $deployment->getSequence());
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
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->getSequence());
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
$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->getSequence(),
'resourceInternalId' => $document->getInternalId(),
'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->getSequence());
$document->setAttribute('scheduleInternalId', $schedule->getInternalId());
}
break;
@@ -799,7 +799,7 @@ class V19 extends Migration
*/
public function forEachDocument(callable $callback): void
{
$internalProjectId = $this->project->getSequence();
$internalProjectId = $this->project->getInternalId();
$collections = match ($internalProjectId) {
'console' => $this->collections['console'],
+12 -12
View File
@@ -36,13 +36,13 @@ class V20 extends Migration
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
Console::info('Migrating Collections');
$this->migrateCollections();
// No need to migrate stats for console
if ($this->project->getSequence() !== 'console') {
if ($this->project->getInternalId() !== '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->getSequence();
$internalProjectId = $this->project->getInternalId();
$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->getSequence();
$functionInternalId = $function->getInternalId();
$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->getSequence()}";
$databaseTable = "database_{$database->getInternalId()}";
// Database level
$databaseId = $database->getId();
$databaseInternalId = $database->getSequence();
$databaseInternalId = $database->getInternalId();
$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->getSequence()}";
$collectionTable = "{$databaseTable}_collection_{$collection->getInternalId()}";
Console::log("Migrating Collections of {$collectionTable} {$collection->getId()} ({$collection->getAttribute('name')})");
// Collection level
$collectionId = $collection->getId();
$collectionInternalId = $collection->getSequence();
$collectionInternalId = $collection->getInternalId();
$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->getSequence()}";
$id = "bucket_{$bucket->getInternalId()}";
Console::log("Migrating Bucket {$id} {$bucket->getId()} ({$bucket->getAttribute('name')})");
// Bucket level
$bucketId = $bucket->getId();
$bucketInternalId = $bucket->getSequence();
$bucketInternalId = $bucket->getInternalId();
$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->getSequence(),
'userInternalId' => $document->getInternalId(),
'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->getSequence(),
'userInternalId' => $document->getInternalId(),
'providerType' => MESSAGE_TYPE_SMS,
'identifier' => $document->getAttribute('phone'),
]);
+4 -4
View File
@@ -29,12 +29,12 @@ class V21 extends Migration
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
$this->dbForProject->setNamespace("_{$this->project->getSequence()}");
$this->dbForProject->setNamespace("_{$this->project->getInternalId()}");
Console::info('Migrating Collections');
$this->migrateCollections();
if ($this->project->getSequence() !== 'console') {
if ($this->project->getInternalId() !== 'console') {
Console::info('Migrating Buckets');
$this->migrateBuckets();
}
@@ -51,7 +51,7 @@ class V21 extends Migration
*/
private function migrateCollections(): void
{
$internalProjectId = $this->project->getSequence();
$internalProjectId = $this->project->getInternalId();
$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['$sequence'];
$bucketId = 'bucket_' . $bucket['$internalId'];
Console::log("Migrating Bucket {$bucketId} {$bucket->getId()} ({$bucket->getAttribute('name')})");
+4 -4
View File
@@ -50,7 +50,7 @@ class V22 extends Migration
*/
private function migrateCollections(): void
{
$projectInternalId = $this->project->getSequence();
$projectInternalId = $this->project->getInternalId();
if (empty($projectInternalId)) {
throw new Exception('Project ID is null');
@@ -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 "$sequence"
4. Fill latestDeploymentInternalId with latestDeployment's "$internalId"
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->getSequence())
->setAttribute('latestDeploymentInternalId', $latestDeployment->getInternalId())
->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->getSequence();
$projectInternalId = $this->project->getInternalId();
$collectionType = match ($projectInternalId) {
'console' => 'console',
@@ -68,13 +68,13 @@ class Base extends Action
Permission::delete(Role::any()),
],
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceType' => 'functions',
'entrypoint' => $entrypoint,
'buildCommands' => $function->getAttribute('commands', ''),
'type' => 'vcs',
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getSequence(),
'installationInternalId' => $installation->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'repositoryId' => $function->getAttribute('repositoryId', ''),
'repositoryInternalId' => $function->getAttribute('repositoryInternalId', ''),
@@ -94,7 +94,7 @@ class Base extends Action
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -165,7 +165,7 @@ class Base extends Action
Permission::delete(Role::any()),
],
'resourceId' => $site->getId(),
'resourceInternalId' => $site->getSequence(),
'resourceInternalId' => $site->getInternalId(),
'resourceType' => 'sites',
'buildCommands' => implode(' && ', $commands),
'buildOutput' => $site->getAttribute('outputDirectory', ''),
@@ -173,7 +173,7 @@ class Base extends Action
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
'type' => 'vcs',
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getSequence(),
'installationInternalId' => $installation->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'repositoryId' => $site->getAttribute('repositoryId', ''),
'repositoryInternalId' => $site->getAttribute('repositoryInternalId', ''),
@@ -193,7 +193,7 @@ class Base extends Action
$site = $site
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('sites', $site->getId(), $site);
@@ -208,15 +208,15 @@ class Base extends Action
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'trigger' => 'deployment',
'type' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $site->getId(),
'deploymentResourceInternalId' => $site->getSequence(),
'deploymentResourceInternalId' => $site->getInternalId(),
'deploymentVcsProviderBranch' => $providerBranch,
'status' => 'verified',
'certificateId' => '',
@@ -237,7 +237,7 @@ class Create extends Action
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceId' => $function->getId(),
'resourceType' => 'functions',
'entrypoint' => $entrypoint,
@@ -252,7 +252,7 @@ class Create extends Action
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->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->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceId' => $function->getId(),
'resourceType' => 'functions',
'entrypoint' => $entrypoint,
@@ -291,7 +291,7 @@ class Create extends Action
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -101,7 +101,7 @@ class Delete extends Action
if ($function->getAttribute('latestDeploymentId') === $deployment->getId()) {
$latestDeployment = $dbForProject->findOne('deployments', [
Query::equal('resourceType', ['functions']),
Query::equal('resourceInternalId', [$function->getSequence()]),
Query::equal('resourceInternalId', [$function->getInternalId()]),
Query::orderDesc('$createdAt'),
]);
$function = $dbForProject->updateDocument(
@@ -109,7 +109,7 @@ class Delete extends Action
$function->getId(),
$function
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->isEmpty() ? '' : $latestDeployment->getCreatedAt())
->setAttribute('latestDeploymentInternalId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getSequence())
->setAttribute('latestDeploymentInternalId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getInternalId())
->setAttribute('latestDeploymentId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getId())
->setAttribute('latestDeploymentStatus', $latestDeployment->isEmpty() ? '' : $latestDeployment->getAttribute('status', ''))
);
@@ -105,11 +105,9 @@ class Get extends Action
$response
->setContentType('application/gzip')
->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
->addHeader('Expires', '0')
->addHeader('Pragma', 'no-cache')
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
->addHeader('X-Peak', \memory_get_peak_usage())
->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '-' . $type . '.tar.gz"');
->addHeader('Content-Disposition', 'attachment; filename="' . $deploymentId . '.tar.gz"');
$size = $device->getFileSize($path);
$rangeHeader = $request->getHeader('range');
@@ -96,9 +96,9 @@ class Create extends Action
$destination = $deviceForFunctions->getPath($deploymentId . '.' . \pathinfo('code.tar.gz', PATHINFO_EXTENSION));
$deviceForFunctions->transfer($path, $destination, $deviceForFunctions);
$deployment->removeAttribute('$sequence');
$deployment->removeAttribute('$internalId');
$deployment = $dbForProject->createDocument('deployments', $deployment->setAttributes([
'$sequence' => '',
'$internalId' => '',
'$id' => $deploymentId,
'sourcePath' => $destination,
'totalSize' => $deployment->getAttribute('sourceSize', 0),
@@ -115,7 +115,7 @@ class Create extends Action
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -97,7 +97,7 @@ class Update extends Action
'status' => 'canceled'
]));
if ($deployment->getSequence() === $function->getAttribute('latestDeploymentInternalId', '')) {
if ($deployment->getInternalId() === $function->getAttribute('latestDeploymentInternalId', '')) {
$function = $function->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
}
@@ -142,7 +142,7 @@ class Create extends Base
Permission::delete(Role::any()),
],
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceType' => 'functions',
'entrypoint' => $function->getAttribute('entrypoint', ''),
'buildCommands' => $function->getAttribute('commands', ''),
@@ -152,7 +152,7 @@ class Create extends Base
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -84,7 +84,7 @@ class XList extends Action
}
// Set resource queries
$queries[] = Query::equal('resourceInternalId', [$function->getSequence()]);
$queries[] = Query::equal('resourceInternalId', [$function->getInternalId()]);
$queries[] = Query::equal('resourceType', ['functions']);
/**
@@ -253,10 +253,10 @@ class Create extends Base
$execution = new Document([
'$id' => $executionId,
'$permissions' => !$user->isEmpty() ? [Permission::read(Role::user($user->getId()))] : [],
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceId' => $function->getId(),
'resourceType' => 'functions',
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
'trigger' => (!is_null($scheduledAt)) ? 'schedule' : 'http',
'status' => $status, // waiting / processing / completed / failed / scheduled
@@ -305,7 +305,7 @@ class Create extends Base
'region' => $project->getAttribute('region'),
'resourceType' => ScheduleExecutions::getSupportedResource(),
'resourceId' => $execution->getId(),
'resourceInternalId' => $execution->getSequence(),
'resourceInternalId' => $execution->getInternalId(),
'resourceUpdatedAt' => DateTime::now(),
'projectId' => $project->getId(),
'schedule' => $scheduledAt,
@@ -315,7 +315,7 @@ class Create extends Base
$execution = $execution
->setAttribute('scheduleId', $schedule->getId())
->setAttribute('scheduleInternalId', $schedule->getSequence())
->setAttribute('scheduleInternalId', $schedule->getInternalId())
->setAttribute('scheduledAt', $scheduledAt);
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution));
@@ -386,9 +386,7 @@ class Create extends Base
try {
$version = $function->getAttribute('version', 'v2');
$command = $runtime['startCommand'];
$source = $deployment->getAttribute('buildPath', '');
$extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz';
$command = $version === 'v2' ? '' : "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$command\"";
$command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"';
$executionResponse = $executor->createExecution(
projectId: $project->getId(),
deploymentId: $deployment->getId(),
@@ -396,7 +394,7 @@ class Create extends Base
variables: $vars,
timeout: $function->getAttribute('timeout', 0),
image: $runtime['image'],
source: $source,
source: $deployment->getAttribute('buildPath', ''),
entrypoint: $deployment->getAttribute('entrypoint', ''),
version: $version,
path: $path,
@@ -441,13 +439,13 @@ class Create extends Base
$queueForStatsUsage
->addMetric(METRIC_EXECUTIONS, 1)
->addMetric(str_replace(['{resourceType}'], [RESOURCE_TYPE_FUNCTIONS], METRIC_RESOURCE_TYPE_EXECUTIONS), 1)
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS), 1)
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS), 1)
->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project
->addMetric(str_replace(['{resourceType}'], [RESOURCE_TYPE_FUNCTIONS], METRIC_RESOURCE_TYPE_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(METRIC_EXECUTIONS_MB_SECONDS, (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->addMetric(str_replace(['{resourceType}'], [RESOURCE_TYPE_FUNCTIONS], METRIC_RESOURCE_TYPE_EXECUTIONS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
;
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution));
@@ -84,7 +84,7 @@ class Delete extends Base
throw new Exception(Exception::EXECUTION_NOT_FOUND);
}
if ($execution->getAttribute('resourceType') !== 'functions' && $execution->getAttribute('resourceInternalId') !== $function->getSequence()) {
if ($execution->getAttribute('resourceType') !== 'functions' && $execution->getAttribute('resourceInternalId') !== $function->getInternalId()) {
throw new Exception(Exception::EXECUTION_NOT_FOUND);
}
$status = $execution->getAttribute('status');
@@ -72,7 +72,7 @@ class Get extends Base
$execution = $dbForProject->getDocument('executions', $executionId);
if ($execution->getAttribute('resourceType') !== 'functions' || $execution->getAttribute('resourceInternalId') !== $function->getSequence()) {
if ($execution->getAttribute('resourceType') !== 'functions' || $execution->getAttribute('resourceInternalId') !== $function->getInternalId()) {
throw new Exception(Exception::EXECUTION_NOT_FOUND);
}
@@ -83,7 +83,7 @@ class XList extends Base
}
// Set internal queries
$queries[] = Query::equal('resourceInternalId', [$function->getSequence()]);
$queries[] = Query::equal('resourceInternalId', [$function->getInternalId()]);
$queries[] = Query::equal('resourceType', ['functions']);
/**
@@ -222,7 +222,7 @@ class Create extends Base
'search' => implode(' ', [$functionId, $name, $runtime]),
'version' => 'v5',
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getSequence(),
'installationInternalId' => $installation->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'repositoryId' => '',
'repositoryInternalId' => '',
@@ -237,7 +237,7 @@ class Create extends Base
'region' => $project->getAttribute('region'),
'resourceType' => 'function',
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceUpdatedAt' => DateTime::now(),
'projectId' => $project->getId(),
'schedule' => $function->getAttribute('schedule'),
@@ -246,7 +246,7 @@ class Create extends Base
);
$function->setAttribute('scheduleId', $schedule->getId());
$function->setAttribute('scheduleInternalId', $schedule->getSequence());
$function->setAttribute('scheduleInternalId', $schedule->getInternalId());
// Git connect logic
if (!empty($providerRepositoryId)) {
@@ -262,18 +262,18 @@ class Create extends Base
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getSequence(),
'installationInternalId' => $installation->getInternalId(),
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceType' => 'function',
'providerPullRequestIds' => []
]));
$function->setAttribute('repositoryId', $repository->getId());
$function->setAttribute('repositoryInternalId', $repository->getSequence());
$function->setAttribute('repositoryInternalId', $repository->getInternalId());
}
$function = $dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -316,7 +316,7 @@ class Create extends Base
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -331,7 +331,7 @@ class Create extends Base
Permission::delete(Role::any()),
],
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceType' => 'functions',
'entrypoint' => $function->getAttribute('entrypoint', ''),
'buildCommands' => $function->getAttribute('commands', ''),
@@ -341,7 +341,7 @@ class Create extends Base
$function = $function
->setAttribute('latestDeploymentId', $deployment->getId())
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument('functions', $function->getId(), $function);
@@ -364,16 +364,16 @@ class Create extends Base
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'status' => 'verified',
'type' => 'deployment',
'trigger' => 'manual',
'deploymentId' => !isset($deployment) || $deployment->isEmpty() ? '' : $deployment->getId(),
'deploymentInternalId' => !isset($deployment) || $deployment->isEmpty() ? '' : $deployment->getSequence(),
'deploymentInternalId' => !isset($deployment) || $deployment->isEmpty() ? '' : $deployment->getInternalId(),
'deploymentResourceType' => 'function',
'deploymentResourceId' => $function->getId(),
'deploymentResourceInternalId' => $function->getSequence(),
'deploymentResourceInternalId' => $function->getInternalId(),
'deploymentVcsProviderBranch' => '',
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain]),
@@ -90,7 +90,7 @@ class Update extends Base
}
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
'deploymentCreatedAt' => $deployment->getCreatedAt(),
])));
@@ -105,18 +105,17 @@ class Update extends Base
$queries = [
Query::equal('trigger', ['manual']),
Query::equal('type', ['deployment']),
Query::equal('deploymentResourceType', ['function']),
Query::equal('deploymentResourceInternalId', [$function->getSequence()]),
Query::equal('deploymentVcsProviderBranch', ['']),
Query::equal('projectInternalId', [$project->getSequence()])
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceType", ["function"]),
Query::equal("deploymentResourceInternalId", [$function->getInternalId()]),
Query::equal("deploymentVcsProviderBranch", [""]),
Query::equal("projectInternalId", [$project->getInternalId()])
];
Authorization::skip(fn () => $dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
->setAttribute('deploymentInternalId', $deployment->getInternalId());
Authorization::skip(fn () => $dbForPlatform->updateDocument('rules', $rule->getId(), $rule));
}, $queries));
@@ -175,8 +175,8 @@ class Update extends Base
// Git disconnect logic. Disconnecting only when providerRepositoryId is empty, allowing for continue updates without disconnecting git
if ($isConnected && ($providerRepositoryId !== null && empty($providerRepositoryId))) {
$repositories = $dbForPlatform->find('repositories', [
Query::equal('projectInternalId', [$project->getSequence()]),
Query::equal('resourceInternalId', [$function->getSequence()]),
Query::equal('projectInternalId', [$project->getInternalId()]),
Query::equal('resourceInternalId', [$function->getInternalId()]),
Query::equal('resourceType', ['function']),
Query::limit(100),
]);
@@ -208,18 +208,18 @@ class Update extends Base
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getSequence(),
'installationInternalId' => $installation->getInternalId(),
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceType' => 'function',
'providerPullRequestIds' => []
]));
$repositoryId = $repository->getId();
$repositoryInternalId = $repository->getSequence();
$repositoryInternalId = $repository->getInternalId();
}
$live = true;
@@ -260,7 +260,7 @@ class Update extends Base
'commands' => $commands,
'scopes' => $scopes,
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getSequence(),
'installationInternalId' => $installation->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'repositoryId' => $repositoryId,
'repositoryInternalId' => $repositoryInternalId,
@@ -70,17 +70,17 @@ class Get extends Base
$stats = $usage = [];
$days = $periods[$range];
$metrics = [
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_SUCCESS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_SUCCESS),
str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED),
];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
@@ -96,7 +96,7 @@ class Create extends Base
Permission::delete(Role::team(ID::custom($teamId), 'owner')),
Permission::delete(Role::team(ID::custom($teamId), 'developer')),
],
'resourceInternalId' => $function->getSequence(),
'resourceInternalId' => $function->getInternalId(),
'resourceId' => $function->getId(),
'resourceType' => 'function',
'key' => $key,
@@ -74,7 +74,7 @@ class Delete extends Base
}
$variable = $dbForProject->getDocument('variables', $variableId);
if ($variable === false || $variable->isEmpty() || $variable->getAttribute('resourceInternalId') !== $function->getSequence() || $variable->getAttribute('resourceType') !== 'function') {
if ($variable === false || $variable->isEmpty() || $variable->getAttribute('resourceInternalId') !== $function->getInternalId() || $variable->getAttribute('resourceType') !== 'function') {
throw new Exception(Exception::VARIABLE_NOT_FOUND);
}
@@ -68,7 +68,7 @@ class Get extends Base
if (
$variable === false ||
$variable->isEmpty() ||
$variable->getAttribute('resourceInternalId') !== $function->getSequence() ||
$variable->getAttribute('resourceInternalId') !== $function->getInternalId() ||
$variable->getAttribute('resourceType') !== 'function'
) {
throw new Exception(Exception::VARIABLE_NOT_FOUND);
@@ -81,7 +81,7 @@ class Update extends Base
}
$variable = $dbForProject->getDocument('variables', $variableId);
if ($variable === false || $variable->isEmpty() || $variable->getAttribute('resourceInternalId') !== $function->getSequence() || $variable->getAttribute('resourceType') !== 'function') {
if ($variable === false || $variable->isEmpty() || $variable->getAttribute('resourceInternalId') !== $function->getInternalId() || $variable->getAttribute('resourceType') !== 'function') {
throw new Exception(Exception::VARIABLE_NOT_FOUND);
}
@@ -274,7 +274,7 @@ class Builds extends Action
$deployment->setAttribute('status', 'processing');
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
if ($deployment->getSequence() === $resource->getAttribute('latestDeploymentInternalId', '')) {
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
}
@@ -524,7 +524,7 @@ class Builds extends Action
$deployment->setAttribute('status', 'building');
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
if ($deployment->getSequence() === $resource->getAttribute('latestDeploymentInternalId', '')) {
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
}
@@ -877,10 +877,6 @@ class Builds extends Action
}
}
$deployment->setAttribute('buildLogs', $logs);
$this->afterBuildSuccess($dbForProject, $deployment);
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
$queueForRealtime
@@ -891,9 +887,9 @@ class Builds extends Action
if ($resource->getCollection() === 'sites') {
try {
$rule = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal("projectInternalId", [$project->getSequence()]),
Query::equal("projectInternalId", [$project->getInternalId()]),
Query::equal("type", ["deployment"]),
Query::equal('deploymentInternalId', [$deployment->getSequence()]),
Query::equal('deploymentInternalId', [$deployment->getInternalId()]),
]));
if ($rule->isEmpty()) {
@@ -932,9 +928,9 @@ class Builds extends Action
str_replace(["{resourceType}"], [RESOURCE_TYPE_SITES], METRIC_RESOURCE_TYPE_EXECUTIONS),
str_replace(["{resourceType}"], [RESOURCE_TYPE_SITES], METRIC_RESOURCE_TYPE_EXECUTIONS_COMPUTE),
str_replace(["{resourceType}"], [RESOURCE_TYPE_SITES], METRIC_RESOURCE_TYPE_EXECUTIONS_MB_SECONDS),
str_replace(["{resourceType}", "{resourceInternalId}"], [RESOURCE_TYPE_SITES, $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS),
str_replace(["{resourceType}", "{resourceInternalId}"], [RESOURCE_TYPE_SITES, $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE),
str_replace(["{resourceType}", "{resourceInternalId}"], [RESOURCE_TYPE_SITES, $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS),
str_replace(["{resourceType}", "{resourceInternalId}"], [RESOURCE_TYPE_SITES, $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS),
str_replace(["{resourceType}", "{resourceInternalId}"], [RESOURCE_TYPE_SITES, $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_COMPUTE),
str_replace(["{resourceType}", "{resourceInternalId}"], [RESOURCE_TYPE_SITES, $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_EXECUTIONS_MB_SECONDS),
],
'bannerDisabled' => true,
'projectCheckDisabled' => true,
@@ -1004,7 +1000,7 @@ class Builds extends Action
Permission::read(Role::team(ID::custom($teamId))),
],
'bucketId' => $bucket->getId(),
'bucketInternalId' => $bucket->getSequence(),
'bucketInternalId' => $bucket->getInternalId(),
'name' => $fileName,
'path' => $path,
'signature' => $deviceForFiles->getFileHash($path),
@@ -1023,7 +1019,7 @@ class Builds extends Action
'metadata' => ['content_type' => $deviceForFiles->getFileMimeType($path)],
]);
Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getSequence(), $file));
Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file));
$deployment->setAttribute($key, $fileId);
}
@@ -1032,7 +1028,6 @@ class Builds extends Action
$date = \date('H:i:s');
$logs .= "[$date] [appwrite] Screenshot capturing finished. \n";
$deployment->setAttribute('buildLogs', $logs);
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
$queueForRealtime
@@ -1047,7 +1042,6 @@ class Builds extends Action
$date = \date('H:i:s');
$logs .= "[$date] [appwrite] Screenshot capturing failed. Deployment will continue. \n";
$deployment->setAttribute('buildLogs', $logs);
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
}
}
@@ -1061,7 +1055,7 @@ class Builds extends Action
$deployment->setAttribute('status', 'ready');
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
if ($deployment->getSequence() === $resource->getAttribute('latestDeploymentInternalId', '')) {
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
}
@@ -1082,17 +1076,18 @@ class Builds extends Action
switch ($resource->getCollection()) {
case 'functions':
$resource->setAttribute('deploymentId', $deployment->getId());
$resource->setAttribute('deploymentInternalId', $deployment->getSequence());
$resource->setAttribute('deploymentInternalId', $deployment->getInternalId());
$resource->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
$resource = $dbForProject->updateDocument('functions', $resource->getId(), $resource);
$queries = [
Query::equal('projectInternalId', [$project->getSequence()]),
Query::equal('type', ['deployment']),
Query::equal('deploymentResourceInternalId', [$resource->getSequence()]),
Query::equal("projectInternalId", [$project->getInternalId()]),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceInternalId", [$resource->getInternalId()]),
Query::equal('deploymentResourceType', ['function']),
Query::equal('trigger', ['manual']),
Query::equal('deploymentVcsProviderBranch', ['']),
Query::equal("projectInternalId", [$project->getInternalId()])
];
$rulesUpdated = false;
@@ -1100,30 +1095,31 @@ class Builds extends Action
$rulesUpdated = true;
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
}, $queries);
break;
case 'sites':
$resource->setAttribute('deploymentId', $deployment->getId());
$resource->setAttribute('deploymentInternalId', $deployment->getSequence());
$resource->setAttribute('deploymentInternalId', $deployment->getInternalId());
$resource->setAttribute('deploymentScreenshotDark', $deployment->getAttribute('screenshotDark', ''));
$resource->setAttribute('deploymentScreenshotLight', $deployment->getAttribute('screenshotLight', ''));
$resource->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
$resource = $dbForProject->updateDocument('sites', $resource->getId(), $resource);
$queries = [
Query::equal('projectInternalId', [$project->getSequence()]),
Query::equal('type', ['deployment']),
Query::equal('deploymentResourceInternalId', [$resource->getSequence()]),
Query::equal("projectInternalId", [$project->getInternalId()]),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceInternalId", [$resource->getInternalId()]),
Query::equal('deploymentResourceType', ['site']),
Query::equal('trigger', ['manual']),
Query::equal('deploymentVcsProviderBranch', ['']),
Query::equal("projectInternalId", [$project->getInternalId()])
];
$dbForPlatform->forEach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
}, $queries);
@@ -1149,15 +1145,15 @@ class Builds extends Action
$dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getSequence(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $deployment->getId(),
'deploymentResourceInternalId' => $deployment->getSequence(),
'deploymentResourceInternalId' => $deployment->getInternalId(),
'deploymentVcsProviderBranch' => $branchName,
'status' => 'verified',
'certificateId' => '',
@@ -1169,23 +1165,24 @@ class Builds extends Action
$rule = $dbForPlatform->getDocument('rules', $ruleId);
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
}
$queries = [
Query::equal('projectInternalId', [$project->getSequence()]),
Query::equal('type', ['deployment']),
Query::equal('deploymentResourceInternalId', [$resource->getSequence()]),
Query::equal("projectInternalId", [$project->getInternalId()]),
Query::equal("type", ["deployment"]),
Query::equal("deploymentResourceInternalId", [$resource->getInternalId()]),
Query::equal('deploymentResourceType', ['site']),
Query::equal('deploymentVcsProviderBranch', [$branchName]),
Query::equal('trigger', ['manual']),
Query::equal("deploymentVcsProviderBranch", [$branchName]),
Query::equal("trigger", ['manual']),
Query::equal("projectInternalId", [$project->getInternalId()])
];
$dbForPlatform->foreach('rules', function (Document $rule) use ($dbForPlatform, $deployment) {
$rule = $rule
->setAttribute('deploymentId', $deployment->getId())
->setAttribute('deploymentInternalId', $deployment->getSequence());
->setAttribute('deploymentInternalId', $deployment->getInternalId());
$dbForPlatform->updateDocument('rules', $rule->getId(), $rule);
}, $queries);
}
@@ -1250,7 +1247,7 @@ class Builds extends Action
$deployment->setAttribute('buildLogs', $message);
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
if ($deployment->getSequence() === $resource->getAttribute('latestDeploymentInternalId', '')) {
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
}
@@ -1285,8 +1282,8 @@ class Builds extends Action
->addMetric(METRIC_BUILDS_COMPUTE_SUCCESS, (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_SUCCESS), 1) // per function
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_COMPUTE_SUCCESS), (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_SUCCESS), 1) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE_SUCCESS), (int)$deployment->getAttribute('buildDuration', 0) * 1000);
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_SUCCESS), 1) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE_SUCCESS), (int)$deployment->getAttribute('buildDuration', 0) * 1000);
break;
case 'failed':
$queue
@@ -1294,8 +1291,8 @@ class Builds extends Action
->addMetric(METRIC_BUILDS_COMPUTE_FAILED, (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_FAILED), 1) // per function
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_COMPUTE_FAILED), (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED), 1) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE_FAILED), (int)$deployment->getAttribute('buildDuration', 0) * 1000);
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_FAILED), 1) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE_FAILED), (int)$deployment->getAttribute('buildDuration', 0) * 1000);
break;
}
@@ -1308,27 +1305,14 @@ class Builds extends Action
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_STORAGE), $deployment->getAttribute('buildSize', 0))
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_COMPUTE), (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}'], [$deployment->getAttribute('resourceType')], METRIC_RESOURCE_TYPE_BUILDS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $deployment->getAttribute('buildDuration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS), 1) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE), $deployment->getAttribute('buildSize', 0))
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE), (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $deployment->getAttribute('buildDuration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS), 1) // per function
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE), $deployment->getAttribute('buildSize', 0))
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_COMPUTE), (int)$deployment->getAttribute('buildDuration', 0) * 1000)
->addMetric(str_replace(['{resourceType}', '{resourceInternalId}'], [$deployment->getAttribute('resourceType'), $resource->getInternalId()], METRIC_RESOURCE_TYPE_ID_BUILDS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $deployment->getAttribute('buildDuration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->setProject($project)
->trigger();
}
/**
* Hook to run after build success
*
* @param Database $dbForProject
* @param Document $deployment
* @return void
*/
protected function afterBuildSuccess(Database $dbForProject, Document &$deployment): void
{
assert($dbForProject instanceof Database);
assert($deployment instanceof Document);
}
protected function getRuntime(Document $resource, string $version): array
{
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
@@ -1443,11 +1427,10 @@ class Builds extends Action
$hostname = System::getEnv('_APP_DOMAIN');
$projectId = $project->getId();
$region = $project->getAttribute('region', 'default');
$resourceId = $resource->getId();
$providerTargetUrl = match ($resource->getCollection()) {
'functions' => "{$protocol}://{$hostname}/console/project-{$region}-{$projectId}/functions/function-{$resourceId}",
'sites' => "{$protocol}://{$hostname}/console/project-{$region}-{$projectId}/sites/site-{$resourceId}",
'functions' => "{$protocol}://{$hostname}/console/project-{$projectId}/functions/function-{$resourceId}",
'sites' => "{$protocol}://{$hostname}/console/project-{$projectId}/sites/site-{$resourceId}",
default => throw new \Exception('Invalid resource type')
};
@@ -1483,9 +1466,9 @@ class Builds extends Action
};
$rule = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal("projectInternalId", [$project->getSequence()]),
Query::equal("projectInternalId", [$project->getInternalId()]),
Query::equal("type", ["deployment"]),
Query::equal("deploymentInternalId", [$deployment->getSequence()]),
Query::equal("deploymentInternalId", [$deployment->getInternalId()]),
]));
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https';
@@ -76,7 +76,7 @@ class Create extends Action
Permission::update(Role::user($user->getId())),
Permission::delete(Role::user($user->getId())),
],
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'projectId' => $project->getId(),
'name' => $name,
'expire' => $expire,
@@ -63,7 +63,7 @@ class Delete extends Action
$key = $dbForPlatform->getDocument('devKeys', $keyId);
if ($key === false || $key->isEmpty() || $key->getAttribute('projectInternalId') !== $project->getSequence()) {
if ($key === false || $key->isEmpty() || $key->getAttribute('projectInternalId') !== $project->getInternalId()) {
throw new Exception(Exception::KEY_NOT_FOUND);
}
@@ -63,7 +63,7 @@ class Get extends Action
$key = $dbForPlatform->getDocument('devKeys', $keyId);
if ($key === false || $key->isEmpty() || $key->getAttribute('projectInternalId') !== $project->getSequence()) {
if ($key === false || $key->isEmpty() || $key->getAttribute('projectInternalId') !== $project->getInternalId()) {
throw new Exception(Exception::KEY_NOT_FOUND);
}
@@ -65,7 +65,7 @@ class Update extends Action
$key = $dbForPlatform->getDocument('devKeys', $keyId);
if ($key === false || $key->isEmpty() || $key->getAttribute('projectInternalId') !== $project->getSequence()) {
if ($key === false || $key->isEmpty() || $key->getAttribute('projectInternalId') !== $project->getInternalId()) {
throw new Exception(Exception::KEY_NOT_FOUND);
}
@@ -71,7 +71,7 @@ class XList extends Action
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries[] = Query::equal('projectInternalId', [$project->getSequence()]);
$queries[] = Query::equal('projectInternalId', [$project->getInternalId()]);
$keys = $dbForPlatform->find('devKeys', $queries);
@@ -153,7 +153,7 @@ class Create extends Action
$rule = new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain->get(),
'status' => $status,
'type' => 'api',
@@ -165,16 +165,16 @@ class Create extends Action
$rule = new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getSequence(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain->get(),
'status' => $status,
'type' => 'deployment',
'trigger' => 'manual',
'deploymentId' => $deployment->isEmpty() ? '' : $deployment->getId(),
'deploymentInternalId' => $deployment->isEmpty() ? '' : $deployment->getSequence(),
'deploymentInternalId' => $deployment->isEmpty() ? '' : $deployment->getInternalId(),
'deploymentResourceType' => 'function',
'deploymentResourceId' => $function->getId(),
'deploymentResourceInternalId' => $function->getSequence(),
'deploymentResourceInternalId' => $function->getInternalId(),
'deploymentVcsProviderBranch' => $branch,
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain->get(), $branch]),

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