Remove database dependency from mapper
This commit is contained in:
parent
09e0e948b5
commit
a1718e8a44
2 changed files with 101 additions and 154 deletions
|
@ -2,70 +2,21 @@
|
|||
|
||||
namespace Appwrite\GraphQL\Types;
|
||||
|
||||
use Appwrite\Auth\Validator\Password;
|
||||
use Appwrite\Event\Validator\Event;
|
||||
use Appwrite\GraphQL\Resolvers;
|
||||
use Appwrite\GraphQL\Types;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\Domain;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Appwrite\Network\Validator\IP;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Network\Validator\URL;
|
||||
use Appwrite\Task\Validator\Cron;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Database\Validator\Queries;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Base;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Buckets;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Collections;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Databases;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Deployments;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Documents;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Executions;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Files;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Functions;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Memberships;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Projects;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Teams;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Users;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Variables;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
use Appwrite\Utopia\Response\Model\Attribute;
|
||||
use Exception;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\Permissions;
|
||||
use Utopia\Database\Validator\Roles;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Route;
|
||||
use Utopia\Storage\Validator\File;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\FloatValidator;
|
||||
use Utopia\Validator\HexColor;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\JSON;
|
||||
use Utopia\Validator\Numeric;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class Mapper
|
||||
{
|
||||
private static array $models = [];
|
||||
private static array $defaultArgs = [];
|
||||
|
||||
private static array $routeBlacklist = [
|
||||
private static array $args = [];
|
||||
private static array $blacklist = [
|
||||
'v1/mock',
|
||||
'v1/graphql',
|
||||
];
|
||||
|
@ -74,7 +25,7 @@ class Mapper
|
|||
{
|
||||
self::$models = $models;
|
||||
|
||||
self::$defaultArgs = [
|
||||
self::$args = [
|
||||
'id' => [
|
||||
'id' => [
|
||||
'type' => Type::nonNull(Type::string()),
|
||||
|
@ -94,18 +45,18 @@ class Mapper
|
|||
],
|
||||
];
|
||||
|
||||
$defaultTypes = [
|
||||
Model::TYPE_BOOLEAN => Type::boolean(),
|
||||
Model::TYPE_STRING => Type::string(),
|
||||
Model::TYPE_INTEGER => Type::int(),
|
||||
Model::TYPE_FLOAT => Type::float(),
|
||||
Model::TYPE_DATETIME => Type::string(),
|
||||
Model::TYPE_JSON => Types::json(),
|
||||
Response::MODEL_NONE => Types::json(),
|
||||
Response::MODEL_ANY => Types::json(),
|
||||
$defaults = [
|
||||
'boolean' => Type::boolean(),
|
||||
'string' => Type::string(),
|
||||
'integer' => Type::int(),
|
||||
'double' => Type::float(),
|
||||
'datetime' => Type::string(),
|
||||
'json' => Types::json(),
|
||||
'none' => Types::json(),
|
||||
'any' => Types::json(),
|
||||
];
|
||||
|
||||
foreach ($defaultTypes as $type => $default) {
|
||||
foreach ($defaults as $type => $default) {
|
||||
Registry::set($type, $default);
|
||||
}
|
||||
}
|
||||
|
@ -116,17 +67,17 @@ class Mapper
|
|||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public static function argumentsFor(string $key): array
|
||||
public static function args(string $key): array
|
||||
{
|
||||
if (isset(self::$defaultArgs[$key])) {
|
||||
return self::$defaultArgs[$key];
|
||||
}
|
||||
return [];
|
||||
return self::$args[$key] ?? [];
|
||||
}
|
||||
|
||||
public static function route(App $utopia, Route $route): iterable
|
||||
{
|
||||
foreach (self::$routeBlacklist as $blacklist) {
|
||||
public static function route(
|
||||
App $utopia,
|
||||
Route $route,
|
||||
callable $complexity
|
||||
): iterable {
|
||||
foreach (self::$blacklist as $blacklist) {
|
||||
if (\str_starts_with($route->getPath(), $blacklist)) {
|
||||
return;
|
||||
}
|
||||
|
@ -138,7 +89,7 @@ class Mapper
|
|||
: [static::$models[$names]];
|
||||
|
||||
foreach ($models as $model) {
|
||||
$type = Mapper::fromResponseModel(\ucfirst($model->getType()));
|
||||
$type = Mapper::model(\ucfirst($model->getType()));
|
||||
$description = $route->getDesc();
|
||||
$params = [];
|
||||
$list = false;
|
||||
|
@ -147,7 +98,7 @@ class Mapper
|
|||
if ($name === 'queries') {
|
||||
$list = true;
|
||||
}
|
||||
$parameterType = Mapper::fromRouteParameter(
|
||||
$parameterType = Mapper::param(
|
||||
$utopia,
|
||||
$parameter['validator'],
|
||||
!$parameter['optional'],
|
||||
|
@ -170,13 +121,7 @@ class Mapper
|
|||
];
|
||||
|
||||
if ($list) {
|
||||
$field['complexity'] = function (int $complexity, array $args) {
|
||||
$queries = Query::parseQueries($args['queries'] ?? []);
|
||||
$query = Query::getByType($queries, Query::TYPE_LIMIT)[0] ?? null;
|
||||
$limit = $query ? $query->getValue() : APP_LIMIT_LIST_DEFAULT;
|
||||
|
||||
return $complexity * $limit;
|
||||
};
|
||||
$field['complexity'] = $complexity;
|
||||
}
|
||||
|
||||
yield $field;
|
||||
|
@ -189,7 +134,7 @@ class Mapper
|
|||
* @param string $name
|
||||
* @return Type
|
||||
*/
|
||||
public static function fromResponseModel(string $name): Type
|
||||
public static function model(string $name): Type
|
||||
{
|
||||
if (Registry::has($name)) {
|
||||
return Registry::get($name);
|
||||
|
@ -258,7 +203,7 @@ class Mapper
|
|||
* @return Type
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fromRouteParameter(
|
||||
public static function param(
|
||||
App $utopia,
|
||||
Validator|callable $validator,
|
||||
bool $required,
|
||||
|
@ -269,70 +214,69 @@ class Mapper
|
|||
: $validator;
|
||||
|
||||
switch ((!empty($validator)) ? $validator::class : '') {
|
||||
case CNAME::class:
|
||||
case Cron::class:
|
||||
case CustomId::class:
|
||||
case Domain::class:
|
||||
case Email::class:
|
||||
case Event::class:
|
||||
case HexColor::class:
|
||||
case Host::class:
|
||||
case IP::class:
|
||||
case Key::class:
|
||||
case Origin::class:
|
||||
case Password::class:
|
||||
case Text::class:
|
||||
case UID::class:
|
||||
case URL::class:
|
||||
case WhiteList::class:
|
||||
case 'Appwrite\Network\Validator\CNAME':
|
||||
case 'Appwrite\Task\Validator\Cron':
|
||||
case 'Appwrite\Utopia\Database\Validator\CustomId':
|
||||
case 'Appwrite\Network\Validator\Domain':
|
||||
case 'Appwrite\Network\Validator\Email':
|
||||
case 'Appwrite\Event\Validator\Event':
|
||||
case 'Utopia\Validator\HexColor':
|
||||
case 'Appwrite\Network\Validator\Host':
|
||||
case 'Appwrite\Network\Validator\IP':
|
||||
case 'Utopia\Database\Validator\Key':
|
||||
case 'Appwrite\Network\Validator\Origin':
|
||||
case 'Appwrite\Auth\Validator\Password':
|
||||
case 'Utopia\Validator\Text':
|
||||
case 'Utopia\Database\Validator\UID':
|
||||
case 'Appwrite\Network\Validator\URL':
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
default:
|
||||
$type = Type::string();
|
||||
break;
|
||||
case Authorization::class:
|
||||
case Base::class:
|
||||
case Buckets::class:
|
||||
case Collections::class:
|
||||
case Databases::class:
|
||||
case Deployments::class:
|
||||
case Documents::class:
|
||||
case Executions::class:
|
||||
case Files::class:
|
||||
case Functions::class:
|
||||
case Memberships::class:
|
||||
case Permissions::class:
|
||||
case Projects::class:
|
||||
case Queries::class:
|
||||
case Roles::class:
|
||||
case Teams::class:
|
||||
case Users::class:
|
||||
case Variables::class:
|
||||
case 'Utopia\Database\Validator\Authorization':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Base':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Buckets':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Collections':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Databases':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Deployments':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Documents':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Executions':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Files':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Functions':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Memberships':
|
||||
case 'Utopia\Database\Validator\Permissions':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Projects':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries':
|
||||
case 'Utopia\Database\Validator\Roles':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Teams':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Users':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Variables':
|
||||
$type = Type::listOf(Type::string());
|
||||
break;
|
||||
case Boolean::class:
|
||||
case 'Utopia\Validator\Boolean':
|
||||
$type = Type::boolean();
|
||||
break;
|
||||
case ArrayList::class:
|
||||
/** @noinspection PhpPossiblePolymorphicInvocationInspection */
|
||||
$type = Type::listOf(self::fromRouteParameter(
|
||||
case 'Utopia\Validator\ArrayList':
|
||||
$type = Type::listOf(self::param(
|
||||
$utopia,
|
||||
$validator->getValidator(),
|
||||
$required,
|
||||
$injections
|
||||
));
|
||||
break;
|
||||
case Integer::class:
|
||||
case Numeric::class:
|
||||
case Range::class:
|
||||
case 'Utopia\Validator\Integer':
|
||||
case 'Utopia\Validator\Numeric':
|
||||
case 'Utopia\Validator\Range':
|
||||
$type = Type::int();
|
||||
break;
|
||||
case FloatValidator::class:
|
||||
case 'Utopia\Validator\FloatValidator':
|
||||
$type = Type::float();
|
||||
break;
|
||||
case Assoc::class:
|
||||
case JSON::class:
|
||||
case 'Utopia\Validator\Assoc':
|
||||
case 'Utopia\Validator\JSON':
|
||||
$type = Types::json();
|
||||
break;
|
||||
case File::class:
|
||||
case 'Utopia\Storage\Validator\File':
|
||||
$type = Types::inputFile();
|
||||
break;
|
||||
}
|
||||
|
@ -353,16 +297,20 @@ class Mapper
|
|||
* @return Type
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function fromCollectionAttribute(string $type, bool $array, bool $required): Type
|
||||
public static function attribute(string $type, bool $array, bool $required): Type
|
||||
{
|
||||
if ($array) {
|
||||
return Type::listOf(self::fromCollectionAttribute($type, false, $required));
|
||||
return Type::listOf(self::attribute(
|
||||
$type,
|
||||
false,
|
||||
$required
|
||||
));
|
||||
}
|
||||
|
||||
$type = match ($type) {
|
||||
Database::VAR_BOOLEAN => Type::boolean(),
|
||||
Database::VAR_INTEGER => Type::int(),
|
||||
Database::VAR_FLOAT => Type::float(),
|
||||
'boolean' => Type::boolean(),
|
||||
'integer' => Type::int(),
|
||||
'double' => Type::float(),
|
||||
default => Type::string(),
|
||||
};
|
||||
|
||||
|
@ -382,7 +330,7 @@ class Mapper
|
|||
}
|
||||
|
||||
$complexModel = self::$models[$type];
|
||||
return self::fromResponseModel(\ucfirst($complexModel->getType()));
|
||||
return self::model(\ucfirst($complexModel->getType()));
|
||||
}
|
||||
|
||||
private static function getUnionType(string $name, array $rule): Type
|
||||
|
@ -395,7 +343,7 @@ class Mapper
|
|||
|
||||
$types = [];
|
||||
foreach ($rule['type'] as $type) {
|
||||
$types[] = self::fromResponseModel(\ucfirst($type));
|
||||
$types[] = self::model(\ucfirst($type));
|
||||
}
|
||||
|
||||
$unionType = new UnionType([
|
||||
|
@ -413,6 +361,8 @@ class Mapper
|
|||
|
||||
private static function getUnionImplementation(string $name, array $object): Type
|
||||
{
|
||||
// FIXME: Find a different way to do this
|
||||
|
||||
switch ($name) {
|
||||
case 'Attributes':
|
||||
return static::getAttributeImplementation($object);
|
||||
|
@ -427,23 +377,20 @@ class Mapper
|
|||
{
|
||||
switch ($object['type']) {
|
||||
case 'string':
|
||||
switch ($object['format']) {
|
||||
case 'email':
|
||||
return static::fromResponseModel('AttributeEmail');
|
||||
case 'url':
|
||||
return static::fromResponseModel('AttributeUrl');
|
||||
case 'ip':
|
||||
return static::fromResponseModel('AttributeIp');
|
||||
}
|
||||
return static::fromResponseModel('AttributeString');
|
||||
return match ($object['format'] ?? '') {
|
||||
'email' => static::model('AttributeEmail'),
|
||||
'url' => static::model('AttributeUrl'),
|
||||
'ip' => static::model('AttributeIp'),
|
||||
default => static::model('AttributeString'),
|
||||
};
|
||||
case 'integer':
|
||||
return static::fromResponseModel('AttributeInteger');
|
||||
return static::model('AttributeInteger');
|
||||
case 'double':
|
||||
return static::fromResponseModel('AttributeFloat');
|
||||
return static::model('AttributeFloat');
|
||||
case 'boolean':
|
||||
return static::fromResponseModel('AttributeBoolean');
|
||||
return static::model('AttributeBoolean');
|
||||
case 'datetime':
|
||||
return static::fromResponseModel('AttributeDatetime');
|
||||
return static::model('AttributeDatetime');
|
||||
}
|
||||
|
||||
throw new Exception('Unknown attribute implementation');
|
||||
|
@ -453,19 +400,19 @@ class Mapper
|
|||
{
|
||||
switch ($object['type']) {
|
||||
case 'argon2':
|
||||
return static::fromResponseModel('AlgoArgon2');
|
||||
return static::model('AlgoArgon2');
|
||||
case 'bcrypt':
|
||||
return static::fromResponseModel('AlgoBcrypt');
|
||||
return static::model('AlgoBcrypt');
|
||||
case 'md5':
|
||||
return static::fromResponseModel('AlgoMd5');
|
||||
return static::model('AlgoMd5');
|
||||
case 'phpass':
|
||||
return static::fromResponseModel('AlgoPhpass');
|
||||
return static::model('AlgoPhpass');
|
||||
case 'scrypt':
|
||||
return static::fromResponseModel('AlgoScrypt');
|
||||
return static::model('AlgoScrypt');
|
||||
case 'scryptMod':
|
||||
return static::fromResponseModel('AlgoScryptModified');
|
||||
return static::model('AlgoScryptModified');
|
||||
case 'sha':
|
||||
return static::fromResponseModel('AlgoSha');
|
||||
return static::model('AlgoSha');
|
||||
}
|
||||
|
||||
throw new Exception('Unknown hash options implementation');
|
||||
|
|
|
@ -23,7 +23,7 @@ class BuilderTest extends TestCase
|
|||
public function testCreateTypeMapping()
|
||||
{
|
||||
$model = $this->response->getModel(Response::MODEL_COLLECTION);
|
||||
$type = Mapper::fromResponseModel(\ucfirst($model->getType()));
|
||||
$type = Mapper::model(\ucfirst($model->getType()));
|
||||
$this->assertEquals('Collection', $type->name);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue