mirror of
https://github.com/appwrite/appwrite
synced 2026-04-21 21:47:16 +00:00
Merge branch '1.8.x' into ci/remove-stave-state
This commit is contained in:
commit
a151959903
28 changed files with 192 additions and 128 deletions
3
.env
3
.env
|
|
@ -133,4 +133,5 @@ _APP_PROJECT_REGIONS=default
|
|||
_APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000
|
||||
_APP_STATS_USAGE_DUAL_WRITING_DBS=database_db_main
|
||||
_APP_TRUSTED_HEADERS=x-forwarded-for
|
||||
_APP_POOL_ADAPTER=stack
|
||||
_APP_POOL_ADAPTER=stack
|
||||
_APP_WORKER_SCREENSHOTS_ROUTER=http://appwrite
|
||||
|
|
|
|||
8
.github/workflows/benchmark.yml
vendored
8
.github/workflows/benchmark.yml
vendored
|
|
@ -3,6 +3,7 @@ concurrency:
|
|||
group: '${{ github.workflow }}-${{ github.ref }}'
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
COMPOSE_FILE: docker-compose.yml
|
||||
IMAGE: appwrite-dev
|
||||
CACHE_KEY: 'appwrite-dev-${{ github.event.pull_request.head.sha }}'
|
||||
'on':
|
||||
|
|
@ -13,7 +14,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Set up Docker Buildx
|
||||
|
|
@ -28,6 +29,7 @@ jobs:
|
|||
cache-from: type=gha
|
||||
cache-to: 'type=gha,mode=max'
|
||||
outputs: 'type=docker,dest=/tmp/${{ env.IMAGE }}.tar'
|
||||
target: development
|
||||
build-args: |
|
||||
DEBUG=false
|
||||
TESTING=true
|
||||
|
|
@ -45,7 +47,7 @@ jobs:
|
|||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
|
|
@ -97,7 +99,7 @@ jobs:
|
|||
echo "| 200 | $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json) | $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark-latest.json) | " >> benchmark.txt
|
||||
echo "| P99 | $(jq -r '.latencyPercentiles.p99' benchmark.json ) | $(jq -r '.latencyPercentiles.p99' benchmark-latest.json ) | " >> benchmark.txt
|
||||
- name: Save results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v6
|
||||
if: '${{ !cancelled() }}'
|
||||
with:
|
||||
name: benchmark.json
|
||||
|
|
|
|||
2
.github/workflows/cleanup-cache.yml
vendored
2
.github/workflows/cleanup-cache.yml
vendored
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cleanup
|
||||
run: |
|
||||
|
|
|
|||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
|
|
@ -34,7 +34,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
|
|
|
|||
6
.github/workflows/linter.yml
vendored
6
.github/workflows/linter.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
|
|
@ -20,9 +20,9 @@ jobs:
|
|||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: |
|
||||
docker run --rm -v $PWD:/app composer sh -c \
|
||||
docker run --rm -v $PWD:/app composer:2.8 sh -c \
|
||||
"composer validate"
|
||||
- name: Run Linter
|
||||
run: |
|
||||
docker run --rm -v $PWD:/app composer sh -c \
|
||||
docker run --rm -v $PWD:/app composer:2.8 sh -c \
|
||||
"composer install --profile --ignore-platform-reqs && composer lint"
|
||||
|
|
|
|||
6
.github/workflows/nightly.yml
vendored
6
.github/workflows/nightly.yml
vendored
|
|
@ -10,11 +10,11 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build the Docker image
|
||||
run: docker build . -t appwrite_image:latest
|
||||
run: DOCKER_BUILDKIT=1 docker build . --target production -t appwrite_image:latest
|
||||
- name: Run Trivy vulnerability scanner on image
|
||||
uses: aquasecurity/trivy-action@0.20.0
|
||||
with:
|
||||
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Run Trivy vulnerability scanner on filesystem
|
||||
uses: aquasecurity/trivy-action@0.20.0
|
||||
with:
|
||||
|
|
|
|||
9
.github/workflows/pr-scan.yml
vendored
9
.github/workflows/pr-scan.yml
vendored
|
|
@ -11,19 +11,20 @@ jobs:
|
|||
pull-requests: write
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: Build the Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
load: true
|
||||
tags: pr_image:${{ github.sha }}
|
||||
target: production
|
||||
|
||||
- name: Run Trivy vulnerability scanner on image
|
||||
uses: aquasecurity/trivy-action@0.20.0
|
||||
|
|
@ -44,7 +45,7 @@ jobs:
|
|||
|
||||
- name: Process Trivy scan results
|
||||
id: process-results
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
|
|
|||
4
.github/workflows/publish.yml
vendored
4
.github/workflows/publish.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 2
|
||||
submodules: recursive
|
||||
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
type=ref,event=tag
|
||||
|
||||
- name: Build & Publish to DockerHub
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
|
|
|||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
type=semver,pattern={{major}}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
|
|
|||
5
.github/workflows/sdk-preview.yml
vendored
5
.github/workflows/sdk-preview.yml
vendored
|
|
@ -1,5 +1,8 @@
|
|||
name: "SDK Preview"
|
||||
|
||||
env:
|
||||
COMPOSE_FILE: docker-compose.yml
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
|
|
@ -19,7 +22,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set SDK type
|
||||
id: set-sdk
|
||||
|
|
|
|||
4
.github/workflows/static-analysis.yml
vendored
4
.github/workflows/static-analysis.yml
vendored
|
|
@ -8,11 +8,11 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run CodeQL
|
||||
run: |
|
||||
docker run --rm -v $PWD:/app composer:2.6 sh -c \
|
||||
docker run --rm -v $PWD:/app composer:2.8 sh -c \
|
||||
"composer install --profile --ignore-platform-reqs && composer check"
|
||||
|
||||
- name: Run Locale check
|
||||
|
|
|
|||
22
.github/workflows/tests.yml
vendored
22
.github/workflows/tests.yml
vendored
|
|
@ -5,6 +5,7 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
COMPOSE_FILE: docker-compose.yml
|
||||
IMAGE: appwrite-dev
|
||||
CACHE_KEY: appwrite-dev-${{ github.event.pull_request.head.sha }}
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ jobs:
|
|||
database_changed: ${{ steps.check.outputs.database_changed }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Fetch base branch
|
||||
run: git fetch origin ${{ github.event.pull_request.base.ref }}
|
||||
|
|
@ -48,7 +49,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
|
|
@ -65,6 +66,7 @@ jobs:
|
|||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=docker,dest=/tmp/${{ env.IMAGE }}.tar
|
||||
target: development
|
||||
build-args: |
|
||||
DEBUG=false
|
||||
TESTING=true
|
||||
|
|
@ -86,7 +88,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -132,7 +134,7 @@ jobs:
|
|||
pull-requests: write
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -217,7 +219,7 @@ jobs:
|
|||
]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -332,7 +334,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -397,7 +399,7 @@ jobs:
|
|||
pull-requests: write
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -457,7 +459,7 @@ jobs:
|
|||
]
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -515,7 +517,7 @@ jobs:
|
|||
pull-requests: write
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -576,7 +578,7 @@ jobs:
|
|||
]
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v4
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@ use Utopia\Pools\Group;
|
|||
use Utopia\Queue\Broker\Pool as BrokerPool;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\Span\Exporter;
|
||||
use Utopia\Span\Span;
|
||||
use Utopia\Span\Storage;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Telemetry\Adapter\None as NoTelemetry;
|
||||
|
||||
|
|
@ -340,6 +337,5 @@ $cli
|
|||
$cli->shutdown()->action(fn () => Timer::clearAll());
|
||||
|
||||
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
Span::setStorage(new Storage\Coroutine());
|
||||
Span::addExporter(new Exporter\Stdout());
|
||||
require_once __DIR__ . '/init/span.php';
|
||||
run($cli->run(...));
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ use Utopia\Logger\Log;
|
|||
use Utopia\Logger\Log\User;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\Platform\Service;
|
||||
use Utopia\Span\Span;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Text;
|
||||
|
|
@ -1245,17 +1246,7 @@ Http::error()
|
|||
$trace = $error->getTrace();
|
||||
|
||||
if (php_sapi_name() === 'cli') {
|
||||
Console::error('[Error] Timestamp: ' . date('c', time()));
|
||||
|
||||
if ($route) {
|
||||
Console::error('[Error] Method: ' . $route->getMethod());
|
||||
Console::error('[Error] URL: ' . $route->getPath());
|
||||
}
|
||||
|
||||
Console::error('[Error] Type: ' . get_class($error));
|
||||
Console::error('[Error] Message: ' . $message);
|
||||
Console::error('[Error] File: ' . $file);
|
||||
Console::error('[Error] Line: ' . $line);
|
||||
Span::error($error);
|
||||
}
|
||||
|
||||
switch ($class) {
|
||||
|
|
|
|||
64
app/http.php
64
app/http.php
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
require_once __DIR__ . '/init/span.php';
|
||||
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
|
|
@ -31,6 +32,7 @@ use Utopia\Http\Http;
|
|||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Log\User;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\Span\Span;
|
||||
use Utopia\System\System;
|
||||
|
||||
const DOMAIN_SYNC_TIMER = 30; // 30 seconds
|
||||
|
|
@ -167,7 +169,6 @@ $http->on(Constant::EVENT_WORKER_START, function ($server, $workerId) use (&$fil
|
|||
$files = new Files();
|
||||
$files->load(__DIR__ . '/../public');
|
||||
}
|
||||
Console::success('Worker ' . ++$workerId . ' started successfully');
|
||||
});
|
||||
|
||||
$http->on(Constant::EVENT_WORKER_STOP, function ($server, $workerId) {
|
||||
|
|
@ -207,17 +208,18 @@ function createDatabase(Http $app, string $resourceKey, string $dbName, array $c
|
|||
}
|
||||
}
|
||||
|
||||
Console::success("[Setup] - $dbName database init started...");
|
||||
Span::init("database.setup");
|
||||
Span::add('database.name', $dbName);
|
||||
|
||||
// Attempt to create the database
|
||||
try {
|
||||
Console::info(" └── Creating database: $dbName...");
|
||||
$database->create();
|
||||
} catch (\Exception $e) {
|
||||
Console::info(" └── Skip: metadata table already exists");
|
||||
Span::add('database.exists', true);
|
||||
}
|
||||
|
||||
// Process collections
|
||||
$collectionsCreated = 0;
|
||||
foreach ($collections as $key => $collection) {
|
||||
if (($collection['$collection'] ?? '') !== Database::METADATA) {
|
||||
continue;
|
||||
|
|
@ -227,8 +229,6 @@ function createDatabase(Http $app, string $resourceKey, string $dbName, array $c
|
|||
continue;
|
||||
}
|
||||
|
||||
Console::info(" └── Creating collection: {$collection['$id']}...");
|
||||
|
||||
$attributes = array_map(fn ($attr) => new Document([
|
||||
'$id' => ID::custom($attr['$id']),
|
||||
'type' => $attr['type'],
|
||||
|
|
@ -250,14 +250,19 @@ function createDatabase(Http $app, string $resourceKey, string $dbName, array $c
|
|||
]), $collection['indexes']);
|
||||
|
||||
$database->createCollection($key, $attributes, $indexes);
|
||||
$collectionsCreated++;
|
||||
}
|
||||
|
||||
Span::add('database.collections_created', $collectionsCreated);
|
||||
|
||||
if ($extraSetup) {
|
||||
$extraSetup($database);
|
||||
}
|
||||
|
||||
Span::current()?->finish();
|
||||
}
|
||||
|
||||
$http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $register) {
|
||||
$http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $totalWorkers, $register) {
|
||||
$app = new Http('UTC');
|
||||
|
||||
go(function () use ($register, $app) {
|
||||
|
|
@ -282,7 +287,6 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
}
|
||||
|
||||
if ($dbForPlatform->getDocument('buckets', 'default')->isEmpty()) {
|
||||
Console::info(" └── Creating default bucket...");
|
||||
$dbForPlatform->createDocument('buckets', new Document([
|
||||
'$id' => ID::custom('default'),
|
||||
'$collection' => ID::custom('buckets'),
|
||||
|
|
@ -305,7 +309,6 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
|
||||
$bucket = $dbForPlatform->getDocument('buckets', 'default');
|
||||
|
||||
Console::info(" └── Creating files collection for default bucket...");
|
||||
$files = $collections['buckets']['files'] ?? [];
|
||||
if (empty($files)) {
|
||||
throw new Exception('Files collection is not configured.');
|
||||
|
|
@ -335,7 +338,6 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
}
|
||||
|
||||
if ($authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots')->isEmpty())) {
|
||||
Console::info(" └── Creating screenshots bucket...");
|
||||
$authorization->skip(fn () => $dbForPlatform->createDocument('buckets', new Document([
|
||||
'$id' => ID::custom('screenshots'),
|
||||
'$collection' => ID::custom('buckets'),
|
||||
|
|
@ -353,7 +355,6 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
|
||||
$bucket = $authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
|
||||
|
||||
Console::info(" └── Creating files collection for screenshots bucket...");
|
||||
$files = $collections['buckets']['files'] ?? [];
|
||||
if (empty($files)) {
|
||||
throw new Exception('Files collection is not configured.');
|
||||
|
|
@ -391,6 +392,9 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
$cache = $app->getResource('cache');
|
||||
|
||||
foreach ($sharedTablesV2 as $hostname) {
|
||||
Span::init('database.setup');
|
||||
Span::add('database.hostname', $hostname);
|
||||
|
||||
$adapter = new DatabasePool($pools->get($hostname));
|
||||
$dbForProject = (new Database($adapter, $cache))
|
||||
->setDatabase('appwrite')
|
||||
|
|
@ -399,10 +403,9 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
->setNamespace(System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', ''));
|
||||
|
||||
try {
|
||||
Console::success('[Setup] - Creating project database: ' . $hostname . '...');
|
||||
$dbForProject->create();
|
||||
} catch (DuplicateException) {
|
||||
Console::success('[Setup] - Skip: metadata table already exists');
|
||||
Span::add('database.exists', true);
|
||||
}
|
||||
|
||||
if ($dbForProject->getCollection(AuditAdapterSQL::COLLECTION)->isEmpty()) {
|
||||
|
|
@ -411,6 +414,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
$audit->setup();
|
||||
}
|
||||
|
||||
$collectionsCreated = 0;
|
||||
foreach ($projectCollections as $key => $collection) {
|
||||
if (($collection['$collection'] ?? '') !== Database::METADATA) {
|
||||
continue;
|
||||
|
|
@ -422,17 +426,21 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
$attributes = \array_map(fn ($attribute) => new Document($attribute), $collection['attributes']);
|
||||
$indexes = \array_map(fn (array $index) => new Document($index), $collection['indexes']);
|
||||
|
||||
Console::success('[Setup] - Creating project collection: ' . $collection['$id'] . '...');
|
||||
|
||||
$dbForProject->createCollection($key, $attributes, $indexes);
|
||||
$collectionsCreated++;
|
||||
}
|
||||
}
|
||||
|
||||
Console::success('[Setup] - Server database init completed...');
|
||||
Span::add('database.collections_created', $collectionsCreated);
|
||||
Span::current()?->finish();
|
||||
}
|
||||
});
|
||||
|
||||
Console::success('Server started successfully (max payload is ' . number_format($payloadSize) . ' bytes)');
|
||||
Console::info("Master pid {$http->master_pid}, manager pid {$http->manager_pid}");
|
||||
Span::init('http.server.start');
|
||||
Span::add('server.workers', $totalWorkers);
|
||||
Span::add('server.payload_size', $payloadSize);
|
||||
Span::add('server.master_pid', $http->master_pid);
|
||||
Span::add('server.manager_pid', $http->manager_pid);
|
||||
Span::current()?->finish();
|
||||
|
||||
// Start the task that starts fetching custom domains
|
||||
$http->task([], 0);
|
||||
|
|
@ -445,12 +453,16 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
});
|
||||
|
||||
$http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) use ($register, &$files) {
|
||||
Span::init('http.request');
|
||||
|
||||
Http::setResource('swooleRequest', fn () => $swooleRequest);
|
||||
Http::setResource('swooleResponse', fn () => $swooleResponse);
|
||||
|
||||
$request = new Request($swooleRequest);
|
||||
$response = new Response($swooleResponse);
|
||||
|
||||
Span::add('http.method', $request->getMethod());
|
||||
|
||||
if ($files instanceof Files && $files->isFileLoaded($request->getURI())) {
|
||||
$time = (60 * 60 * 24 * 45); // 45 days cache
|
||||
|
||||
|
|
@ -479,7 +491,12 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
|
|||
$authorization->addRole(Role::any()->toString());
|
||||
|
||||
$app->run($request, $response);
|
||||
|
||||
$route = $app->getRoute();
|
||||
Span::add('http.path', $route?->getPath() ?? 'unknown');
|
||||
} catch (\Throwable $th) {
|
||||
Span::error($th);
|
||||
|
||||
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
$logger = $app->getResource("logger");
|
||||
|
|
@ -542,12 +559,6 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
|
|||
}
|
||||
}
|
||||
|
||||
Console::error('[Error] Type: ' . get_class($th));
|
||||
Console::error('[Error] Message: ' . $th->getMessage());
|
||||
Console::error('[Error] File: ' . $th->getFile());
|
||||
Console::error('[Error] Line: ' . $th->getLine());
|
||||
Console::error('[Error] Trace: ' . $th->getTraceAsString());
|
||||
|
||||
$swooleResponse->setStatusCode(500);
|
||||
|
||||
$output = ((Http::isDevelopment())) ? [
|
||||
|
|
@ -564,6 +575,9 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
|
|||
];
|
||||
|
||||
$swooleResponse->end(\json_encode($output));
|
||||
} finally {
|
||||
Span::add('http.response.code', $response->getStatusCode());
|
||||
Span::current()?->finish();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
8
app/init/span.php
Normal file
8
app/init/span.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
use Utopia\Span\Exporter;
|
||||
use Utopia\Span\Span;
|
||||
use Utopia\Span\Storage;
|
||||
|
||||
Span::setStorage(new Storage\Coroutine());
|
||||
Span::addExporter(new Exporter\Pretty());
|
||||
|
|
@ -45,17 +45,13 @@ use Utopia\Queue\Message;
|
|||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Queue\Server;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\Span\Exporter;
|
||||
use Utopia\Span\Span;
|
||||
use Utopia\Span\Storage;
|
||||
use Utopia\Storage\Device\Telemetry as TelemetryDevice;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Telemetry\Adapter as Telemetry;
|
||||
use Utopia\Telemetry\Adapter\None as NoTelemetry;
|
||||
|
||||
Runtime::enableCoroutine();
|
||||
Span::setStorage(new Storage\Coroutine());
|
||||
Span::addExporter(new Exporter\Stdout());
|
||||
require_once __DIR__ . '/init/span.php';
|
||||
|
||||
global $register;
|
||||
Server::setResource('register', fn () => $register);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
"utopia-php/detector": "0.2.*",
|
||||
"utopia-php/domains": "1.*",
|
||||
"utopia-php/emails": "0.6.*",
|
||||
"utopia-php/dns": "1.5.*",
|
||||
"utopia-php/dns": "1.6.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/fetch": "0.5.*",
|
||||
|
|
@ -68,6 +68,7 @@
|
|||
"utopia-php/migration": "1.5.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "1.*",
|
||||
"utopia-php/span": "1.1.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.15.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
|
|
@ -91,7 +92,7 @@
|
|||
"appwrite/sdk-generator": "*",
|
||||
"phpunit/phpunit": "9.*",
|
||||
"swoole/ide-helper": "6.*",
|
||||
"phpstan/phpstan": "1.8.*",
|
||||
"phpstan/phpstan": "1.12.*",
|
||||
"textalk/websocket": "1.5.*",
|
||||
"laravel/pint": "1.*",
|
||||
"phpbench/phpbench": "1.*"
|
||||
|
|
|
|||
55
composer.lock
generated
55
composer.lock
generated
|
|
@ -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": "57189be7990142e6a44a13eefdfe3043",
|
||||
"content-hash": "9397ae16877660a3ea485cfdcaab906c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -3948,22 +3948,22 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/dns",
|
||||
"version": "1.5.4",
|
||||
"version": "1.6.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/dns.git",
|
||||
"reference": "ee831a6f2ceb28babb042ea65539c26ea4530bf6"
|
||||
"reference": "98c70520213a41e2fe1867e5b110273c06bf1cab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/ee831a6f2ceb28babb042ea65539c26ea4530bf6",
|
||||
"reference": "ee831a6f2ceb28babb042ea65539c26ea4530bf6",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/98c70520213a41e2fe1867e5b110273c06bf1cab",
|
||||
"reference": "98c70520213a41e2fe1867e5b110273c06bf1cab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"utopia-php/domains": "1.0.*",
|
||||
"utopia-php/span": "1.0.*",
|
||||
"utopia-php/span": "1.1.*",
|
||||
"utopia-php/telemetry": "*",
|
||||
"utopia-php/validators": "0.*"
|
||||
},
|
||||
|
|
@ -3999,9 +3999,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/dns/issues",
|
||||
"source": "https://github.com/utopia-php/dns/tree/1.5.4"
|
||||
"source": "https://github.com/utopia-php/dns/tree/1.6.2"
|
||||
},
|
||||
"time": "2026-02-02T10:40:38+00:00"
|
||||
"time": "2026-02-13T12:29:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
|
@ -4909,25 +4909,26 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/span",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/span.git",
|
||||
"reference": "f2f6c499ded3a776e8019902e83d140ff0f89693"
|
||||
"reference": "49d04aa588a2cdbbc9381ee7a1c129469e0f905c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/span/zipball/f2f6c499ded3a776e8019902e83d140ff0f89693",
|
||||
"reference": "f2f6c499ded3a776e8019902e83d140ff0f89693",
|
||||
"url": "https://api.github.com/repos/utopia-php/span/zipball/49d04aa588a2cdbbc9381ee7a1c129469e0f905c",
|
||||
"reference": "49d04aa588a2cdbbc9381ee7a1c129469e0f905c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
"php": ">=8.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.0",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"rector/rector": "^2.3",
|
||||
"swoole/ide-helper": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
|
|
@ -4946,9 +4947,9 @@
|
|||
"description": "Simple span tracing library for PHP with coroutine support",
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/span/issues",
|
||||
"source": "https://github.com/utopia-php/span/tree/1.0.0"
|
||||
"source": "https://github.com/utopia-php/span/tree/1.1.4"
|
||||
},
|
||||
"time": "2026-01-12T20:05:10+00:00"
|
||||
"time": "2026-02-13T10:58:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
|
|
@ -6238,16 +6239,11 @@
|
|||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.8.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "46e223dd68a620da18855c23046ddb00940b4014"
|
||||
},
|
||||
"version": "1.12.32",
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/46e223dd68a620da18855c23046ddb00940b4014",
|
||||
"reference": "46e223dd68a620da18855c23046ddb00940b4014",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/2770dcdf5078d0b0d53f94317e06affe88419aa8",
|
||||
"reference": "2770dcdf5078d0b0d53f94317e06affe88419aa8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -6276,8 +6272,11 @@
|
|||
"static analysis"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://phpstan.org/user-guide/getting-started",
|
||||
"forum": "https://github.com/phpstan/phpstan/discussions",
|
||||
"issues": "https://github.com/phpstan/phpstan/issues",
|
||||
"source": "https://github.com/phpstan/phpstan/tree/1.8.11"
|
||||
"security": "https://github.com/phpstan/phpstan/security/policy",
|
||||
"source": "https://github.com/phpstan/phpstan-src"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -6287,13 +6286,9 @@
|
|||
{
|
||||
"url": "https://github.com/phpstan",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-10-24T15:45:13+00:00"
|
||||
"time": "2025-09-30T10:16:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
|
|
@ -8919,5 +8914,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -564,6 +564,7 @@ services:
|
|||
environment:
|
||||
# Specific
|
||||
- _APP_BROWSER_HOST
|
||||
- _APP_WORKER_SCREENSHOTS_ROUTER
|
||||
# Basic
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ class Create extends Base
|
|||
|
||||
if ($async) {
|
||||
if (is_null($scheduledAt)) {
|
||||
if (System::getEnv('_APP_REGION') !== 'nyc') { // TODO: Remove region check
|
||||
if ($project->getId() != '6862e6a6000cce69f9da') {
|
||||
$execution = $authorization->skip(fn () => $dbForProject->createDocument('executions', $execution));
|
||||
}
|
||||
$queueForFunctions
|
||||
|
|
@ -344,7 +344,7 @@ class Create extends Base
|
|||
->setAttribute('scheduleInternalId', $schedule->getSequence())
|
||||
->setAttribute('scheduledAt', $scheduledAt);
|
||||
|
||||
if (System::getEnv('_APP_REGION') !== 'nyc') { // TODO: Remove region check
|
||||
if ($project->getId() != '6862e6a6000cce69f9da') {
|
||||
$execution = $authorization->skip(fn () => $dbForProject->createDocument('executions', $execution));
|
||||
}
|
||||
}
|
||||
|
|
@ -505,7 +505,7 @@ class Create extends Base
|
|||
->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)))
|
||||
;
|
||||
|
||||
if (System::getEnv('_APP_REGION') !== 'nyc') { // TODO: Remove region check
|
||||
if ($project->getId() != '6862e6a6000cce69f9da') {
|
||||
$execution = $authorization->skip(fn () => $dbForProject->createDocument('executions', $execution));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,15 +111,16 @@ class Screenshots extends Action
|
|||
throw new \Exception('Bucket not found');
|
||||
}
|
||||
|
||||
$routerHost = System::getEnv('_APP_WORKER_SCREENSHOTS_ROUTER', 'http://appwrite');
|
||||
$configs = [
|
||||
'screenshotLight' => [
|
||||
'headers' => [ 'x-appwrite-hostname' => $rule->getAttribute('domain') ],
|
||||
'url' => 'http://appwrite/?appwrite-preview=1&appwrite-theme=light',
|
||||
'url' => $routerHost . '/?appwrite-preview=1&appwrite-theme=light',
|
||||
'theme' => 'light'
|
||||
],
|
||||
'screenshotDark' => [
|
||||
'headers' => [ 'x-appwrite-hostname' => $rule->getAttribute('domain') ],
|
||||
'url' => 'http://appwrite/?appwrite-preview=1&appwrite-theme=dark',
|
||||
'url' => $routerHost . '/?appwrite-preview=1&appwrite-theme=dark',
|
||||
'theme' => 'dark'
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use Utopia\Database\Database;
|
|||
use Utopia\Database\Document;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Queue\Message;
|
||||
use Utopia\System\System;
|
||||
|
||||
class Executions extends Action
|
||||
{
|
||||
|
|
@ -45,7 +44,8 @@ class Executions extends Action
|
|||
throw new Exception('Missing execution');
|
||||
}
|
||||
|
||||
if (System::getEnv('_APP_REGION') !== 'nyc') { // TODO: Remove region check
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
if ($project->getId() != '6862e6a6000cce69f9da') {
|
||||
$dbForProject->upsertDocument('executions', $execution);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,6 +185,14 @@ class Client
|
|||
$responseHeaders = [];
|
||||
$cookies = [];
|
||||
|
||||
if (isset($params['queries'])) {
|
||||
foreach ($params['queries'] as $value) {
|
||||
if (!is_string($value)) {
|
||||
throw new Exception('Queries must be converted to strings');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query = match ($headers['content-type']) {
|
||||
'application/json' => json_encode($params),
|
||||
'multipart/form-data' => $this->flatten($params),
|
||||
|
|
|
|||
|
|
@ -2430,22 +2430,36 @@ trait DatabasesBase
|
|||
$this->assertEquals($document['title'], $response['body']['title']);
|
||||
$this->assertEquals($document['releaseYear'], $response['body']['releaseYear']);
|
||||
$this->assertArrayNotHasKey('birthDay', $response['body']);
|
||||
|
||||
$sequence = $response['body']['$sequence'];
|
||||
|
||||
// Query by sequence
|
||||
// Query by sequence on get single document route
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $document['$collectionId'] . '/documents/' . $document['$id'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('$sequence', [$sequence])
|
||||
Query::equal('$sequence', [$sequence])->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
$this->assertEquals('Invalid query method: equal', $response['body']['message']);
|
||||
|
||||
// Query by sequence
|
||||
$response = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $document['$collectionId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('$sequence', [$sequence.''])->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals($document['title'], $response['body']['title']);
|
||||
$this->assertEquals($document['releaseYear'], $response['body']['releaseYear']);
|
||||
$this->assertTrue(array_key_exists('$sequence', $response['body']));
|
||||
$this->assertEquals($document['title'], $response['body']['documents'][0]['title']);
|
||||
$this->assertEquals($document['releaseYear'], $response['body']['documents'][0]['releaseYear']);
|
||||
$this->assertTrue(array_key_exists('$sequence', $response['body']['documents'][0]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2358,6 +2358,36 @@ trait DatabasesBase
|
|||
$this->assertEquals($row['title'], $response['body']['title']);
|
||||
$this->assertEquals($row['releaseYear'], $response['body']['releaseYear']);
|
||||
$this->assertArrayNotHasKey('birthDay', $response['body']);
|
||||
|
||||
$sequence = $response['body']['$sequence'];
|
||||
|
||||
// Query by sequence on get single row route
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $row['$tableId'] . '/rows/' . $row['$id'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('$sequence', [$sequence])->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
$this->assertEquals('Invalid query method: equal', $response['body']['message']);
|
||||
|
||||
// Query by sequence
|
||||
$response = $this->client->call(Client::METHOD_GET, '/tablesdb/' . $databaseId . '/tables/' . $row['$tableId'] . '/rows', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('$sequence', [$sequence.''])->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals($row['title'], $response['body']['rows'][0]['title']);
|
||||
$this->assertEquals($row['releaseYear'], $response['body']['rows'][0]['releaseYear']);
|
||||
$this->assertTrue(array_key_exists('$sequence', $response['body']['rows'][0]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -546,7 +546,7 @@ class ProxyCustomServerTest extends Scope
|
|||
|
||||
$rules = $this->listRules([
|
||||
'search' => $rule1Domain,
|
||||
'queries' => [ Query::orderDesc('$createdAt') ]
|
||||
'queries' => [ Query::orderDesc('$createdAt')->toString() ]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $rules['headers']['status-code']);
|
||||
|
|
@ -555,7 +555,7 @@ class ProxyCustomServerTest extends Scope
|
|||
|
||||
$rules = $this->listRules([
|
||||
'search' => $rule2Domain,
|
||||
'queries' => [ Query::orderDesc('$createdAt') ]
|
||||
'queries' => [ Query::orderDesc('$createdAt')->toString() ]
|
||||
]);
|
||||
$this->assertEquals(200, $rules['headers']['status-code']);
|
||||
$ruleIds = \array_column($rules['body']['rules'], '$id');
|
||||
|
|
@ -563,7 +563,7 @@ class ProxyCustomServerTest extends Scope
|
|||
|
||||
$rules = $this->listRules([
|
||||
'search' => $rule1Id,
|
||||
'queries' => [ Query::orderDesc('$createdAt') ]
|
||||
'queries' => [ Query::orderDesc('$createdAt')->toString() ]
|
||||
]);
|
||||
$this->assertEquals(200, $rules['headers']['status-code']);
|
||||
$ruleDomains = \array_column($rules['body']['rules'], 'domain');
|
||||
|
|
@ -571,7 +571,7 @@ class ProxyCustomServerTest extends Scope
|
|||
|
||||
$rules = $this->listRules([
|
||||
'search' => $rule2Id,
|
||||
'queries' => [ Query::orderDesc('$createdAt') ]
|
||||
'queries' => [ Query::orderDesc('$createdAt')->toString() ]
|
||||
]);
|
||||
$this->assertEquals(200, $rules['headers']['status-code']);
|
||||
$ruleDomains = \array_column($rules['body']['rules'], 'domain');
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ class SitesCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('deploymentResourceId', [$siteId])
|
||||
Query::equal('deploymentResourceId', [$siteId])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue