Not found exception

This commit is contained in:
Jake Barnby
2024-11-04 20:57:08 +13:00
parent ca5d9ce96a
commit c59cd97eb8
4 changed files with 89 additions and 102 deletions
+74 -89
View File
@@ -3,7 +3,6 @@
use Appwrite\Auth\Auth;
use Appwrite\Detector\Detector;
use Appwrite\Event\Database as EventDatabase;
use Appwrite\Event\Delete;
use Appwrite\Event\Event;
use Appwrite\Event\Usage;
use Appwrite\Extend\Exception;
@@ -26,6 +25,7 @@ use Utopia\Database\Exception\Authorization as AuthorizationException;
use Utopia\Database\Exception\Conflict as ConflictException;
use Utopia\Database\Exception\Duplicate as DuplicateException;
use Utopia\Database\Exception\Limit as LimitException;
use Utopia\Database\Exception\NotFound as NotFoundException;
use Utopia\Database\Exception\Query as QueryException;
use Utopia\Database\Exception\Restricted as RestrictedException;
use Utopia\Database\Exception\Structure as StructureException;
@@ -352,13 +352,16 @@ function updateAttribute(
if ($type === Database::VAR_RELATIONSHIP) {
$primaryDocumentOptions = \array_merge($attribute->getAttribute('options', []), $options);
$attribute->setAttribute('options', $primaryDocumentOptions);
$dbForProject->updateRelationship(
collection: $collectionId,
id: $key,
newKey: $newKey,
onDelete: $primaryDocumentOptions['onDelete'],
);
try {
$dbForProject->updateRelationship(
collection: $collectionId,
id: $key,
newKey: $newKey,
onDelete: $primaryDocumentOptions['onDelete'],
);
} catch (NotFoundException) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
}
if ($primaryDocumentOptions['twoWay']) {
$relatedCollection = $dbForProject->getDocument('database_' . $db->getInternalId(), $primaryDocumentOptions['relatedCollection']);
@@ -388,6 +391,8 @@ function updateAttribute(
);
} catch (TruncateException) {
throw new Exception(Exception::ATTRIBUTE_INVALID_RESIZE);
} catch (NotFoundException) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
}
}
@@ -530,12 +535,7 @@ App::get('/v1/databases')
->inject('response')
->inject('dbForProject')
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries = Query::parseQueries($queries);
if (!empty($search)) {
$queries[] = Query::search('search', $search);
@@ -849,7 +849,7 @@ App::post('/v1/databases/:databaseId/collections')
});
App::get('/v1/databases/:databaseId/collections')
->alias('/v1/database/collections', ['databaseId' => 'default'])
->alias('/v1/database/collections')
->desc('List collections')
->groups(['api', 'database'])
->label('scope', 'collections.read')
@@ -875,11 +875,7 @@ App::get('/v1/databases/:databaseId/collections')
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries = Query::parseQueries($queries);
if (!empty($search)) {
$queries[] = Query::search('search', $search);
@@ -919,7 +915,7 @@ App::get('/v1/databases/:databaseId/collections')
});
App::get('/v1/databases/:databaseId/collections/:collectionId')
->alias('/v1/database/collections/:collectionId', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId')
->desc('Get collection')
->groups(['api', 'database'])
->label('scope', 'collections.read')
@@ -954,7 +950,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId')
});
App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
->alias('/v1/database/collections/:collectionId/logs', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/logs')
->desc('List collection logs')
->groups(['api', 'database'])
->label('scope', 'collections.read')
@@ -988,12 +984,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries = Query::parseQueries($queries);
$grouped = Query::groupByType($queries);
$limit = $grouped['limit'] ?? APP_LIMIT_COUNT;
$offset = $grouped['offset'] ?? 0;
@@ -1055,7 +1046,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
App::put('/v1/databases/:databaseId/collections/:collectionId')
->alias('/v1/database/collections/:collectionId', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId')
->desc('Update collection')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
@@ -1106,7 +1097,8 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
->setAttribute('$permissions', $permissions)
->setAttribute('documentSecurity', $documentSecurity)
->setAttribute('enabled', $enabled)
->setAttribute('search', implode(' ', [$collectionId, $name])));
->setAttribute('search', \implode(' ', [$collectionId, $name]))
);
$dbForProject->updateCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $permissions, $documentSecurity);
@@ -1119,7 +1111,7 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
});
App::delete('/v1/databases/:databaseId/collections/:collectionId')
->alias('/v1/database/collections/:collectionId', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId')
->desc('Delete collection')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
@@ -1175,7 +1167,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId')
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string')
->alias('/v1/database/collections/:collectionId/attributes/string', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/string')
->desc('Create string attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1226,14 +1218,13 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string
'filters' => $filters,
]), $response, $dbForProject, $queueForDatabase, $queueForEvents);
$response
->setStatusCode(Response::STATUS_CODE_ACCEPTED)
->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING);
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email')
->alias('/v1/database/collections/:collectionId/attributes/email', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/email')
->desc('Create email attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1276,7 +1267,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email'
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
->alias('/v1/database/collections/:collectionId/attributes/enum', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/enum')
->desc('Create enum attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1324,7 +1315,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip')
->alias('/v1/database/collections/:collectionId/attributes/ip', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/ip')
->desc('Create IP address attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1367,7 +1358,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip')
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url')
->alias('/v1/database/collections/:collectionId/attributes/url', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/url')
->desc('Create URL attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1410,7 +1401,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url')
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/integer')
->alias('/v1/database/collections/:collectionId/attributes/integer', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/integer')
->desc('Create integer attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1440,8 +1431,8 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/intege
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) {
// Ensure attribute default is within range
$min = (is_null($min)) ? PHP_INT_MIN : \intval($min);
$max = (is_null($max)) ? PHP_INT_MAX : \intval($max);
$min = \is_null($min) ? PHP_INT_MIN : $min;
$max = \is_null($max) ? PHP_INT_MAX : $max;
if ($min > $max) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
@@ -1482,7 +1473,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/intege
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float')
->alias('/v1/database/collections/:collectionId/attributes/float', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/float')
->desc('Create float attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1512,21 +1503,16 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float'
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?float $min, ?float $max, ?float $default, bool $array, Response $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents) {
// Ensure attribute default is within range
$min = (is_null($min)) ? -PHP_FLOAT_MAX : \floatval($min);
$max = (is_null($max)) ? PHP_FLOAT_MAX : \floatval($max);
$min = \is_null($min) ? -PHP_FLOAT_MAX : $min;
$max = \is_null($max) ? PHP_FLOAT_MAX : $max;
if ($min > $max) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
}
// Ensure default value is a float
if (!is_null($default)) {
$default = \floatval($default);
}
$validator = new Range($min, $max, Database::VAR_FLOAT);
if (!is_null($default) && !$validator->isValid($default)) {
if (!\is_null($default) && !$validator->isValid($default)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
}
@@ -1557,7 +1543,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float'
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boolean')
->alias('/v1/database/collections/:collectionId/attributes/boolean', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/boolean')
->desc('Create boolean attribute')
->groups(['api', 'database', 'schema'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1599,7 +1585,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boolea
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/datetime')
->alias('/v1/database/collections/:collectionId/attributes/datetime', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/datetime')
->desc('Create datetime attribute')
->groups(['api', 'database'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1644,7 +1630,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/dateti
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relationship')
->alias('/v1/database/collections/:collectionId/attributes/relationship', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/relationship')
->desc('Create relationship attribute')
->groups(['api', 'database'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
@@ -1773,7 +1759,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/relati
});
App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
->alias('/v1/database/collections/:collectionId/attributes', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes')
->desc('List attributes')
->groups(['api', 'database'])
->label('scope', 'collections.read')
@@ -1804,16 +1790,12 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries = Query::parseQueries($queries);
\array_push(
$queries,
Query::equal('databaseInternalId', [$database->getInternalId()]),
Query::equal('collectionInternalId', [$collection->getInternalId()]),
Query::equal('databaseInternalId', [$database->getInternalId()])
);
/**
@@ -1822,6 +1804,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
$cursor = \array_filter($queries, function ($query) {
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
});
$cursor = \reset($cursor);
if ($cursor) {
@@ -1832,8 +1815,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
$attributeId = $cursor->getValue();
$cursorDocument = Authorization::skip(fn () => $dbForProject->find('attributes', [
Query::equal('collectionInternalId', [$collection->getInternalId()]),
Query::equal('databaseInternalId', [$database->getInternalId()]),
Query::equal('collectionInternalId', [$collection->getInternalId()]),
Query::equal('key', [$attributeId]),
Query::limit(1),
]));
@@ -1857,7 +1840,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
});
App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
->alias('/v1/database/collections/:collectionId/attributes/:key', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/:key')
->desc('Get attribute')
->groups(['api', 'database'])
->label('scope', 'collections.read')
@@ -2390,7 +2373,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/attributes/:key/
});
App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
->alias('/v1/database/collections/:collectionId/attributes/:key', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/attributes/:key')
->desc('Delete attribute')
->groups(['api', 'database', 'schema'])
->label('scope', 'collections.write')
@@ -2504,7 +2487,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
});
App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
->alias('/v1/database/collections/:collectionId/indexes', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/indexes')
->desc('Create index')
->groups(['api', 'database'])
->label('event', 'databases.[databaseId].collections.[collectionId].indexes.[indexId].create')
@@ -2675,7 +2658,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
});
App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
->alias('/v1/database/collections/:collectionId/indexes', ['databaseId' => 'default'])
->alias('/v1/database/collections/:collectionId/indexes')
->desc('List indexes')
->groups(['api', 'database'])
->label('scope', 'collections.read')
@@ -2706,13 +2689,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
try {
$queries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$queries = Query::parseQueries($queries);
\array_push($queries, Query::equal('collectionId', [$collectionId]), Query::equal('databaseId', [$databaseId]));
\array_push(
$queries,
Query::equal('databaseId', [$databaseId]),
Query::equal('collectionId', [$collectionId]),
);
/**
* Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries
@@ -3042,10 +3025,12 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
try {
$document = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $document);
} catch (StructureException $exception) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
} catch (DuplicateException $exception) {
} catch (StructureException $e) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage());
} catch (DuplicateException $e) {
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
} catch (NotFoundException $e) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
// Add $collectionId and $databaseId for all documents
@@ -3176,14 +3161,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
$cursor->setValue($cursorDocument);
}
try {
$documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries);
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT);
} catch (AuthorizationException) {
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries);
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT);
// Add $collectionId and $databaseId for all documents
$processDocument = (function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database): bool {
@@ -3647,8 +3626,10 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (DuplicateException) {
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
} catch (StructureException $exception) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $exception->getMessage());
} catch (StructureException $e) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage());
} catch (NotFoundException $e) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
// Add $collectionId and $databaseId for all documents
@@ -3757,12 +3738,16 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
}
$dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $database, $collection, $documentId) {
$dbForProject->deleteDocument(
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
$documentId
);
});
try {
$dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $database, $collection, $documentId) {
$dbForProject->deleteDocument(
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
$documentId
);
});
} catch (NotFoundException $e) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
// Add $collectionId and $databaseId for all documents
$processDocument = function (Document $collection, Document $document) use (&$processDocument, $dbForProject, $database) {
+2
View File
@@ -775,6 +775,8 @@ App::error()
case 'Utopia\Database\Exception\Relationship':
$error = new AppwriteException(AppwriteException::RELATIONSHIP_VALUE_INVALID, $error->getMessage(), previous: $error);
break;
case 'Utopia\Database\Exception\NotFound':
$error = new AppwriteException(AppwriteException::COLLECTION_NOT_FOUND, $error->getMessage(), previous: $error);
}
$code = $error->getCode();
+1 -1
View File
@@ -51,7 +51,7 @@
"utopia-php/cache": "0.10.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.53.10",
"utopia-php/database": "0.53.12",
"utopia-php/domains": "0.5.*",
"utopia-php/dsn": "0.2.1",
"utopia-php/framework": "0.33.*",
Generated
+12 -12
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": "f77f899f6250f080406151dc4cb29f92",
"content-hash": "102bab0efa76adc92312b9c5a7f488e3",
"packages": [
{
"name": "adhocore/jwt",
@@ -1724,32 +1724,32 @@
},
{
"name": "utopia-php/database",
"version": "0.53.10",
"version": "0.53.12",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "39550cb0e32cac45bf5ea1deb96569b837c028b1"
"reference": "4068d0c5c503ec4562f8c0aa9cfd095889418b83"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/39550cb0e32cac45bf5ea1deb96569b837c028b1",
"reference": "39550cb0e32cac45bf5ea1deb96569b837c028b1",
"url": "https://api.github.com/repos/utopia-php/database/zipball/4068d0c5c503ec4562f8c0aa9cfd095889418b83",
"reference": "4068d0c5c503ec4562f8c0aa9cfd095889418b83",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"ext-pdo": "*",
"php": ">=8.0",
"php": ">=8.3",
"utopia-php/cache": "0.10.*",
"utopia-php/framework": "0.33.*",
"utopia-php/mongo": "0.3.*"
},
"require-dev": {
"fakerphp/faker": "1.23.*",
"laravel/pint": "1.17.*",
"pcov/clobber": "2.0.*",
"phpstan/phpstan": "1.11.*",
"phpunit/phpunit": "9.6.*",
"laravel/pint": "1.*",
"pcov/clobber": "2.*",
"phpstan/phpstan": "1.*",
"phpunit/phpunit": "9.*",
"rregeer/phpunit-coverage-check": "0.3.*",
"swoole/ide-helper": "5.1.3",
"utopia-php/cli": "0.14.*"
@@ -1774,9 +1774,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.53.10"
"source": "https://github.com/utopia-php/database/tree/0.53.12"
},
"time": "2024-11-04T02:02:23+00:00"
"time": "2024-11-04T07:51:44+00:00"
},
{
"name": "utopia-php/domains",