mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Begin API Rewrite
This commit is contained in:
+1
-1
@@ -177,7 +177,7 @@ RUN chmod +x /usr/local/bin/doctor && \
|
||||
chmod +x /usr/local/bin/worker-mails && \
|
||||
chmod +x /usr/local/bin/worker-messaging && \
|
||||
chmod +x /usr/local/bin/worker-webhooks && \
|
||||
chmod +x /usr/local/bin/worker-transfers
|
||||
chmod +x /usr/local/bin/worker-imports
|
||||
|
||||
# Letsencrypt Permissions
|
||||
RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/
|
||||
|
||||
+10
-200
@@ -3581,10 +3581,10 @@ $collections = [
|
||||
],
|
||||
],
|
||||
|
||||
'transfers' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'transfers',
|
||||
'name' => 'transfers',
|
||||
'imports' => [
|
||||
'$collection' => ID::custom(Database::METADATA),
|
||||
'$id' => ID::custom('imports'),
|
||||
'name' => 'Imports',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => ID::custom('status'),
|
||||
@@ -3612,18 +3612,7 @@ $collections = [
|
||||
'$id' => ID::custom('source'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('destination'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'size' => 8192,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
@@ -3642,7 +3631,7 @@ $collections = [
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('totalProgress'),
|
||||
'$id' => ID::custom('statusCounters'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 3000,
|
||||
@@ -3653,10 +3642,10 @@ $collections = [
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestProgress'),
|
||||
'$id' => ID::custom('resourceData'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'size' => 131070,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
@@ -3709,16 +3698,9 @@ $collections = [
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_destination',
|
||||
'$id' => '_key_statusCounters',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['destination'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_latestProgress',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['latestProgress'],
|
||||
'attributes' => ['statusCounters'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
@@ -3731,178 +3713,6 @@ $collections = [
|
||||
]
|
||||
],
|
||||
],
|
||||
|
||||
'sources' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'sources',
|
||||
'name' => 'sources',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => ID::custom('type'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('name'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('data'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 3000,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('lastCheck'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 65535,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => new \stdClass(),
|
||||
'array' => false,
|
||||
'filters' => ['json'],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('search'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
]
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_type',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['type'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_name',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_fulltext_search'),
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [],
|
||||
'orders' => [],
|
||||
]
|
||||
]
|
||||
],
|
||||
|
||||
'destinations' => [
|
||||
'$collection' => Database::METADATA,
|
||||
'$id' => 'destinations',
|
||||
'name' => 'destinations',
|
||||
'attributes' => [
|
||||
[
|
||||
'$id' => ID::custom('type'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('name'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('data'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 1000,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('lastCheck'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 65535,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => new \stdClass(),
|
||||
'array' => false,
|
||||
'filters' => ['json'],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('search'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
]
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
'$id' => '_key_type',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['type'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_name',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_fulltext_search'),
|
||||
'type' => Database::INDEX_FULLTEXT,
|
||||
'attributes' => ['search'],
|
||||
'lengths' => [],
|
||||
'orders' => [],
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
return $collections;
|
||||
|
||||
+10
-30
@@ -584,40 +584,20 @@ return [
|
||||
'description' => 'Too many queries.',
|
||||
'code' => 400,
|
||||
],
|
||||
// Transfers
|
||||
Exception::TRANSFER_NOT_FOUND => [
|
||||
'name' => Exception::TRANSFER_NOT_FOUND,
|
||||
'description' => 'Transfer with the requested ID could not be found.',
|
||||
// Imports
|
||||
Exception::IMPORT_NOT_FOUND => [
|
||||
'name' => Exception::IMPORT_NOT_FOUND,
|
||||
'description' => 'Import with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TRANSFER_ALREADY_EXISTS => [
|
||||
'name' => Exception::TRANSFER_ALREADY_EXISTS,
|
||||
'description' => 'Transfer with the requested ID already exists.',
|
||||
Exception::IMPORT_ALREADY_EXISTS => [
|
||||
'name' => Exception::IMPORT_ALREADY_EXISTS,
|
||||
'description' => 'Import with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::TRANSFER_SOURCE_NOT_FOUND => [
|
||||
'name' => Exception::TRANSFER_SOURCE_NOT_FOUND,
|
||||
'description' => 'Transfer source with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TRANSFER_DESTINATION_NOT_FOUND => [
|
||||
'name' => Exception::TRANSFER_DESTINATION_NOT_FOUND,
|
||||
'description' => 'Transfer destination with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TRANSFER_SOURCE_FAILED => [
|
||||
'name' => Exception::TRANSFER_SOURCE_FAILED,
|
||||
'description' => 'Transfer source failed to complete the transfer.',
|
||||
'code' => 500,
|
||||
],
|
||||
Exception::TRANSFER_DESTINATION_FAILED => [
|
||||
'name' => Exception::TRANSFER_DESTINATION_FAILED,
|
||||
'description' => 'Transfer destination failed to complete the transfer.',
|
||||
'code' => 500,
|
||||
],
|
||||
Exception::TRANSFER_IN_PROGRESS => [
|
||||
'name' => Exception::TRANSFER_IN_PROGRESS,
|
||||
'description' => 'Transfer is already in progress.',
|
||||
Exception::IMPORT_IN_PROGRESS => [
|
||||
'name' => Exception::IMPORT_IN_PROGRESS,
|
||||
'description' => 'Import is already in progress.',
|
||||
'code' => 409,
|
||||
],
|
||||
];
|
||||
|
||||
+15
-1
@@ -236,5 +236,19 @@ return [
|
||||
'update' => [
|
||||
'$description' => 'This event triggers when a function is updated.',
|
||||
]
|
||||
]
|
||||
],
|
||||
'imports' => [
|
||||
'$model' => Response::MODEL_IMPORT,
|
||||
'$resource' => true,
|
||||
'$description' => 'This event triggers on any imports event.',
|
||||
'create' => [
|
||||
'$description' => 'This event triggers when an import is created.'
|
||||
],
|
||||
'delete' => [
|
||||
'$description' => 'This event triggers when an import is deleted.',
|
||||
],
|
||||
'update' => [
|
||||
'$description' => 'This event triggers when an import is updated.',
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
@@ -51,8 +51,8 @@ $admins = [
|
||||
'functions.write',
|
||||
'execution.read',
|
||||
'execution.write',
|
||||
'transfers.read',
|
||||
'transfers.write'
|
||||
'imports.read',
|
||||
'imports.write'
|
||||
];
|
||||
|
||||
return [
|
||||
|
||||
@@ -76,10 +76,10 @@ return [ // List of publicly visible scopes
|
||||
'health.read' => [
|
||||
'description' => 'Access to read your project\'s health status',
|
||||
],
|
||||
'transfers.read' => [
|
||||
'description' => 'Access to read your project\'s transfer logs',
|
||||
'imports.read' => [
|
||||
'description' => 'Access to read your project\'s import logs',
|
||||
],
|
||||
'transfers.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s sources, destinations, and transfer logs.',
|
||||
'imports.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s imports.',
|
||||
]
|
||||
];
|
||||
|
||||
@@ -199,17 +199,17 @@ return [
|
||||
'optional' => false,
|
||||
'icon' => '',
|
||||
],
|
||||
'transfers' => [
|
||||
'key' => 'transfers',
|
||||
'name' => 'Transfers',
|
||||
'subtitle' => 'The Transfers service allows you to migrate third-party data to your Appwrite server.',
|
||||
'description' => '/docs/services/transfers.md',
|
||||
'controller' => 'api/transfers.php',
|
||||
'imports' => [
|
||||
'key' => 'imports',
|
||||
'name' => 'Imports',
|
||||
'subtitle' => 'The Imports service allows you to migrate third-party data to your Appwrite server.',
|
||||
'description' => '/docs/services/imports.md',
|
||||
'controller' => 'api/imports.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/transfers',
|
||||
'docsUrl' => 'https://appwrite.io/docs/imports',
|
||||
'tests' => true,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/transfers.png',
|
||||
'icon' => '/images/services/imports.png',
|
||||
],
|
||||
];
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
Submodule app/console updated: 9174d8f8cb...ac4181aea4
@@ -845,6 +845,93 @@ App::get('/v1/functions/:functionId/deployments')
|
||||
]), Response::MODEL_DEPLOYMENT_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/functions/:functionId/deployments/:deploymentId/download')
|
||||
->groups(['api', 'functions'])
|
||||
->desc('Download Deployment')
|
||||
->label('scope', 'functions.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'downloadDeployment')
|
||||
->label('sdk.description', '/docs/references/functions/download-deployment.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', '*/*')
|
||||
->label('sdk.methodType', 'location')
|
||||
->param('functionId', '', new UID(), 'Function ID.')
|
||||
->param('deploymentId', '', new UID(), 'Deployment ID.')
|
||||
->inject('response')
|
||||
->inject('request')
|
||||
->inject('dbForProject')
|
||||
->inject('deviceFunctions')
|
||||
->action(function (string $functionId, string $deploymentId, Response $response, Request $request, Database $dbForProject, Device $deviceFunctions) {
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception(Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
if ($deployment->isEmpty()) {
|
||||
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
|
||||
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$path = $deployment->getAttribute('path', '');
|
||||
if (!$deviceFunctions->exists($path)) {
|
||||
throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$response
|
||||
->setContentType('application/gzip')
|
||||
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)) . ' GMT') // 45 days cache
|
||||
->addHeader('X-Peak', \memory_get_peak_usage())
|
||||
->addHeader('Content-Disposition', 'attachment; filename="deployment.tar.gz"')
|
||||
;
|
||||
|
||||
$size = $deviceFunctions->getFileSize($path);
|
||||
$rangeHeader = $request->getHeader('range');
|
||||
|
||||
if (!empty($rangeHeader)) {
|
||||
$start = $request->getRangeStart();
|
||||
$end = $request->getRangeEnd();
|
||||
$unit = $request->getRangeUnit();
|
||||
|
||||
if ($end === null) {
|
||||
$end = min(($start + MAX_OUTPUT_CHUNK_SIZE - 1), ($size - 1));
|
||||
}
|
||||
|
||||
if ($unit !== 'bytes' || $start >= $end || $end >= $size) {
|
||||
throw new Exception(Exception::STORAGE_INVALID_RANGE);
|
||||
}
|
||||
|
||||
$response
|
||||
->addHeader('Accept-Ranges', 'bytes')
|
||||
->addHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $size)
|
||||
->addHeader('Content-Length', $end - $start + 1)
|
||||
->setStatusCode(Response::STATUS_CODE_PARTIALCONTENT);
|
||||
|
||||
$response->send($deviceFunctions->read($path, $start, ($end - $start + 1)));
|
||||
}
|
||||
|
||||
if ($size > APP_STORAGE_READ_BUFFER) {
|
||||
$response->addHeader('Content-Length', $deviceFunctions->getFileSize($path));
|
||||
for ($i = 0; $i < ceil($size / MAX_OUTPUT_CHUNK_SIZE); $i++) {
|
||||
$response->chunk(
|
||||
$deviceFunctions->read(
|
||||
$path,
|
||||
($i * MAX_OUTPUT_CHUNK_SIZE),
|
||||
min(MAX_OUTPUT_CHUNK_SIZE, $size - ($i * MAX_OUTPUT_CHUNK_SIZE))
|
||||
),
|
||||
(($i + 1) * MAX_OUTPUT_CHUNK_SIZE) >= $size
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$response->send($deviceFunctions->read($path));
|
||||
}
|
||||
});
|
||||
|
||||
App::get('/v1/functions/:functionId/deployments/:deploymentId')
|
||||
->groups(['api', 'functions'])
|
||||
->desc('Get Deployment')
|
||||
|
||||
@@ -0,0 +1,403 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Import;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Imports;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Transfer\Transfer;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
include_once __DIR__ . '/../shared/api.php';
|
||||
|
||||
App::get('/v1/imports')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('List Imports')
|
||||
->label('scope', 'imports.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'list')
|
||||
->label('sdk.description', '/docs/references/imports/list-imports.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT_LIST)
|
||||
->param('queries', [], new Imports(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). 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(', ', Imports::ALLOWED_ATTRIBUTES), true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
|
||||
|
||||
$queries = Query::parseQueries($queries);
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE);
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
/** @var Query $cursor */
|
||||
$importId = $cursor->getValue();
|
||||
$cursorDocument = $dbForProject->getDocument('imports', $importId);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Import '{$importId}' for the 'cursor' value not found.");
|
||||
}
|
||||
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'imports' => $dbForProject->find('imports', $queries),
|
||||
'total' => $dbForProject->count('imports', $filterQueries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_IMPORT_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/imports/:importId')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Get Import')
|
||||
->label('scope', 'imports.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'get')
|
||||
->label('sdk.description', '/docs/references/imports/get-import.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT)
|
||||
->param('importId', '', new UID(), 'Import unique ID.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $importId, Response $response, Database $dbForProject) {
|
||||
$import = $dbForProject->getDocument('imports', $importId);
|
||||
|
||||
if ($import->isEmpty()) {
|
||||
throw new Exception(Exception::IMPORT_NOT_FOUND, 'Import not found', 404);
|
||||
}
|
||||
|
||||
$response->dynamic($import, Response::MODEL_IMPORT);
|
||||
});
|
||||
|
||||
App::post('/v1/imports/:importId')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Retry Import')
|
||||
->label('scope', 'imports.write')
|
||||
->label('event', 'imports.[importId].retry')
|
||||
->label('audits.event', 'import.retry')
|
||||
->label('audits.resource', 'imports/{request.importId}')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'retry')
|
||||
->label('sdk.description', '/docs/references/imports/retry-import.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT)
|
||||
->param('importId', '', new UID(), 'Import unique ID.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('events')
|
||||
->action(function (string $importId, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventInstance) {
|
||||
$import = $dbForProject->getDocument('imports', $importId);
|
||||
|
||||
if ($import->isEmpty()) {
|
||||
throw new Exception(Exception::IMPORT_NOT_FOUND);
|
||||
}
|
||||
|
||||
// if ($import->getAttribute('status') !== 'failed') {
|
||||
// throw new Exception(Exception::IMPORT_IN_PROGRESS, 'Import not failed');
|
||||
// }
|
||||
|
||||
$import
|
||||
->setAttribute('status', 'pending')
|
||||
->setAttribute('dateUpdated', \time());
|
||||
|
||||
// Trigger Import
|
||||
$event = new Import();
|
||||
$event
|
||||
->setImport($import)
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->trigger();
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
App::delete('/v1/imports/:importId')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Delete Import')
|
||||
->label('scope', 'imports.write')
|
||||
->label('event', 'imports.[importId].delete')
|
||||
->label('audits.event', 'importId.delete')
|
||||
->label('audits.resource', 'imports/{request.importId}')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'delete')
|
||||
->label('sdk.description', '/docs/references/functions/delete-import.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->param('importId', '', new UID(), 'Import ID.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('deletes')
|
||||
->inject('events')
|
||||
->action(function (string $importId, Response $response, Database $dbForProject, Delete $deletes, Event $events) {
|
||||
|
||||
$import = $dbForProject->getDocument('imports', $importId);
|
||||
|
||||
if ($import->isEmpty()) {
|
||||
throw new Exception(Exception::IMPORT_NOT_FOUND, 'Import not found', 404);
|
||||
}
|
||||
|
||||
if (!$dbForProject->deleteDocument('imports', $import->getId())) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove import from DB', 500);
|
||||
}
|
||||
|
||||
$deletes
|
||||
->setType(DELETE_TYPE_DOCUMENT)
|
||||
->setDocument($import);
|
||||
|
||||
$events->setParam('importId', $import->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
App::post('/v1/imports/appwrite')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Import Appwrite Data')
|
||||
->label('scope', 'imports.write')
|
||||
->label('event', 'imports.create')
|
||||
->label('audits.event', 'import.create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'importAppwrite')
|
||||
->label('sdk.description', '/docs/references/imports/import-appwrite.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT)
|
||||
->param('resources', [], new ArrayList(new WhiteList(Transfer::ALL_PUBLIC_RESOURCES)), 'List of resources to import')
|
||||
->param('endpoint', '', new URL(), "Source's Appwrite Endpoint")
|
||||
->param('projectId', '', new UID(), "Source's Project ID")
|
||||
->param('apiKey', '', new Text(512), "Source's API Key")
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('events')
|
||||
->action(function (array $resources, string $endpoint, string $projectId, string $apiKey, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
||||
$import = $dbForProject->createDocument('imports', new Document([
|
||||
'$id' => ID::unique(),
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => json_encode([
|
||||
'type' => 'appwrite',
|
||||
'endpoint' => $endpoint,
|
||||
'projectId' => $projectId,
|
||||
'apiKey' => $apiKey,
|
||||
]),
|
||||
'resources' => $resources,
|
||||
'statusCounters' => '{}',
|
||||
'resourceData' => "{}",
|
||||
'errorData' => ""
|
||||
]));
|
||||
|
||||
$eventsInstance->setParam('importId', $import->getId());
|
||||
|
||||
// Trigger Transfer
|
||||
$event = new Import();
|
||||
$event
|
||||
->setImport($import)
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->trigger();
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($import, Response::MODEL_IMPORT);
|
||||
});
|
||||
|
||||
App::post('/v1/imports/firebase')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Import Firebase Data')
|
||||
->label('scope', 'imports.write')
|
||||
->label('event', 'imports.create')
|
||||
->label('audits.event', 'import.create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'importFirebase')
|
||||
->label('sdk.description', '/docs/references/imports/import-firebase.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT)
|
||||
->param('resources', [], new ArrayList(new WhiteList(Transfer::ALL_PUBLIC_RESOURCES)), 'List of resources to import')
|
||||
->param('serviceAccount', '', new Text(512), "Source's Service Account")
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('events')
|
||||
->action(function (array $resources, string $serviceAccount, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
||||
$import = $dbForProject->createDocument('imports', new Document([
|
||||
'$id' => ID::unique(),
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => json_encode([
|
||||
'type' => 'firebase',
|
||||
'serviceAccount' => $serviceAccount,
|
||||
]),
|
||||
'resources' => $resources,
|
||||
'statusCounters' => '{}',
|
||||
'resourceData' => "{}",
|
||||
'errorData' => ""
|
||||
]));
|
||||
|
||||
$eventsInstance->setParam('importId', $import->getId());
|
||||
|
||||
// Trigger Transfer
|
||||
$event = new Import();
|
||||
$event
|
||||
->setImport($import)
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->trigger();
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($import, Response::MODEL_IMPORT);
|
||||
});
|
||||
|
||||
App::post('/v1/imports/supabase')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Import Supabase Data')
|
||||
->label('scope', 'imports.write')
|
||||
->label('event', 'imports.create')
|
||||
->label('audits.event', 'import.create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'importSupabase')
|
||||
->label('sdk.description', '/docs/references/imports/import-supabase.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT)
|
||||
->param('resources', [], new ArrayList(new WhiteList(Transfer::ALL_PUBLIC_RESOURCES)), 'List of resources to import')
|
||||
->param('endpoint', '', new URL(), "Source's Supabase Endpoint")
|
||||
->param('apiKey', '', new Text(512), "Source's API Key")
|
||||
->param('databaseHost', '', new Text(512), "Source's Database Host")
|
||||
->param('username', '', new Text(512), "Source's Database Username")
|
||||
->param('password', '', new Text(512), "Source's Database Password")
|
||||
->param('port', 5432, new Integer(), "Source's Database Port", true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('events')
|
||||
->action(function (array $resources, string $endpoint, string $apiKey, string $databaseHost, string $username, string $password, int $port, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
||||
$import = $dbForProject->createDocument('imports', new Document([
|
||||
'$id' => ID::unique(),
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => json_encode([
|
||||
'type' => 'supabase',
|
||||
'endpoint' => $endpoint,
|
||||
'apiKey' => $apiKey,
|
||||
'databaseHost' => $databaseHost,
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'port' => $port,
|
||||
]),
|
||||
'resources' => $resources,
|
||||
'statusCounters' => '{}',
|
||||
'resourceData' => "{}",
|
||||
'errorData' => ""
|
||||
]));
|
||||
|
||||
$eventsInstance->setParam('importId', $import->getId());
|
||||
|
||||
// Trigger Transfer
|
||||
$event = new Import();
|
||||
$event
|
||||
->setImport($import)
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->trigger();
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($import, Response::MODEL_IMPORT);
|
||||
});
|
||||
|
||||
App::post('/v1/imports/nhost')
|
||||
->groups(['api', 'imports'])
|
||||
->desc('Import NHost Data')
|
||||
->label('scope', 'imports.write')
|
||||
->label('event', 'imports.create')
|
||||
->label('audits.event', 'import.create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'imports')
|
||||
->label('sdk.method', 'importNhost')
|
||||
->label('sdk.description', '/docs/references/imports/import-nhost.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_IMPORT)
|
||||
->param('resources', [], new ArrayList(new WhiteList(Transfer::ALL_PUBLIC_RESOURCES)), 'List of resources to import')
|
||||
->param('subdomain', '', new URL(), "Source's Subdomain")
|
||||
->param('region', '', new Text(512), "Source's Region")
|
||||
->param('adminSecret', '', new Text(512), "Source's Admin Secret")
|
||||
->param('database', '', new Text(512), "Source's Database Name")
|
||||
->param('username', '', new Text(512), "Source's Database Username")
|
||||
->param('password', '', new Text(512), "Source's Database Password")
|
||||
->param('port', 5432, new Integer(), "Source's Database Port", true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('events')
|
||||
->action(function (array $resources, string $subdomain, string $region, string $adminSecret, string $database, string $username, string $password, int $port, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
||||
$import = $dbForProject->createDocument('imports', new Document([
|
||||
'$id' => ID::unique(),
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => json_encode([
|
||||
'type' => 'nhost',
|
||||
'subdomain' => $subdomain,
|
||||
'region' => $region,
|
||||
'adminSecret' => $adminSecret,
|
||||
'database' => $database,
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'port' => $port,
|
||||
]),
|
||||
'resources' => $resources,
|
||||
'statusCounters' => '{}',
|
||||
'resourceData' => "{}",
|
||||
'errorData' => ""
|
||||
]));
|
||||
|
||||
$eventsInstance->setParam('importId', $import->getId());
|
||||
|
||||
// Trigger Transfer
|
||||
$event = new Import();
|
||||
$event
|
||||
->setImport($import)
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->trigger();
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($import, Response::MODEL_IMPORT);
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -175,8 +175,6 @@ const APP_AUTH_TYPE_KEY = 'Key';
|
||||
const APP_AUTH_TYPE_ADMIN = 'Admin';
|
||||
// Response related
|
||||
const MAX_OUTPUT_CHUNK_SIZE = 2 * 1024 * 1024; // 2MB
|
||||
// Transfer related
|
||||
const TRANSFER_RESOURCES = ['Users', 'Files', 'Databases', 'Documents', 'Functions'];
|
||||
|
||||
$register = new Registry();
|
||||
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Messaging\Adapter\Realtime;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Appwrite\Permission;
|
||||
use Appwrite\Query;
|
||||
use Appwrite\Resque\Worker;
|
||||
use Appwrite\Role;
|
||||
use Appwrite\Utopia\Response\Model\Import;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Transfer\Destination;
|
||||
use Utopia\Transfer\Destinations\Appwrite as DestinationsAppwrite;
|
||||
use Utopia\Transfer\Resource;
|
||||
use Utopia\Transfer\Source;
|
||||
use Utopia\Transfer\Sources\Appwrite;
|
||||
use Utopia\Transfer\Sources\Firebase;
|
||||
use Utopia\Transfer\Sources\NHost;
|
||||
use Utopia\Transfer\Sources\Supabase;
|
||||
use Utopia\Transfer\Transfer;
|
||||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
Console::title('Imports V1 Worker');
|
||||
Console::success(APP_NAME . ' Imports worker v1 has started');
|
||||
|
||||
class ImportsV1 extends Worker
|
||||
{
|
||||
/**
|
||||
* Database connection shared across all methods of this file
|
||||
*
|
||||
* @var Database
|
||||
*/
|
||||
private Database $dbForProject;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return "imports";
|
||||
}
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->dbForProject = $this->getProjectDB($this->args['project']['$id']);
|
||||
|
||||
// Process
|
||||
$this->processImport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Source
|
||||
*
|
||||
* @return Source
|
||||
* @throws \Exception
|
||||
*/
|
||||
function processSource(array $source): Source
|
||||
{
|
||||
switch ($source['type']) {
|
||||
case 'firebase':
|
||||
return new Firebase(
|
||||
json_decode($source['serviceAccount'], true),
|
||||
);
|
||||
break;
|
||||
case 'supabase':
|
||||
return new Supabase(
|
||||
$source['endpoint'],
|
||||
$source['key'],
|
||||
$source['host'],
|
||||
$source['database'],
|
||||
$source['username'],
|
||||
$source['password'],
|
||||
$source['port'],
|
||||
);
|
||||
break;
|
||||
case 'nhost':
|
||||
return new NHost(
|
||||
$source['subdomain'],
|
||||
$source['region'],
|
||||
$source['adminSecret'],
|
||||
$source['database'],
|
||||
$source['username'],
|
||||
$source['password'],
|
||||
$source['port'],
|
||||
);
|
||||
break;
|
||||
case 'appwrite':
|
||||
return new Appwrite($source['projectId'], $source['endpoint'], $source['apiKey']);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Invalid source type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateImportDocument(Document $import, Document $project): Document
|
||||
{
|
||||
// Trigger Webhook
|
||||
$importModel = new Import();
|
||||
|
||||
$importUpdate = new Event(Event::IMPORTS_QUEUE_NAME, Event::IMPORTS_CLASS_NAME);
|
||||
$importUpdate
|
||||
->setProject($project)
|
||||
->setEvent('imports.[importId].update')
|
||||
->setParam('importId', $import->getId())
|
||||
->setPayload($import->getArrayCopy(array_keys($importModel->getRules())))
|
||||
->trigger();
|
||||
|
||||
/** Trigger Realtime */
|
||||
$allEvents = Event::generateEvents('imports.[importId].update', [
|
||||
'importId' => $import->getId(),
|
||||
]);
|
||||
|
||||
$target = Realtime::fromPayload(
|
||||
event: $allEvents[0],
|
||||
payload: $import,
|
||||
project: $project
|
||||
);
|
||||
|
||||
Realtime::send(
|
||||
projectId: 'console',
|
||||
payload: $import->getArrayCopy(),
|
||||
events: $allEvents,
|
||||
channels: $target['channels'],
|
||||
roles: $target['roles'],
|
||||
);
|
||||
|
||||
return $this->dbForProject->updateDocument('imports', $import->getId(), $import);
|
||||
}
|
||||
|
||||
protected function removeAPIKey(Document $apiKey)
|
||||
{
|
||||
$consoleDB = $this->getConsoleDB();
|
||||
|
||||
$consoleDB->deleteDocument('keys', $apiKey->getId());
|
||||
}
|
||||
|
||||
protected function generateAPIKey(Document $project): Document
|
||||
{
|
||||
$consoleDB = $this->getConsoleDB();
|
||||
$generatedSecret = bin2hex(\random_bytes(128));
|
||||
|
||||
$key = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
'projectInternalId' => $project->getInternalId(),
|
||||
'projectId' => $project->getId(),
|
||||
'name' => 'Transfer API Key',
|
||||
'scopes' => [
|
||||
// Auth
|
||||
'users.read',
|
||||
'users.write',
|
||||
'teams.read',
|
||||
'teams.write',
|
||||
// Database
|
||||
'databases.read',
|
||||
'databases.write',
|
||||
'collections.read',
|
||||
'collections.write',
|
||||
'documents.read',
|
||||
'documents.write',
|
||||
// Storage
|
||||
'buckets.read',
|
||||
'buckets.write',
|
||||
'files.read',
|
||||
'files.write',
|
||||
|
||||
// Functions
|
||||
'functions.read',
|
||||
'functions.write',
|
||||
],
|
||||
'expire' => null,
|
||||
'sdks' => [],
|
||||
'accessedAt' => null,
|
||||
'secret' => $generatedSecret,
|
||||
]);
|
||||
|
||||
return $consoleDB->createDocument('keys', $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Import
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processImport(): void
|
||||
{
|
||||
/**
|
||||
* @var Document $importDocument
|
||||
* @var Transfer $transfer
|
||||
*/
|
||||
$importDocument = null;
|
||||
$transfer = null;
|
||||
$projectDocument = $this->dbForProject->getDocument('projects', $this->args['project']['$id']);
|
||||
$tempAPIKey = $this->generateAPIKey($projectDocument);
|
||||
|
||||
try {
|
||||
$importDocument = $this->dbForProject->getDocument('imports', $this->args['import']['$id']);
|
||||
$importDocument->setAttribute('status', 'processing');
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
|
||||
$source = $this->processSource(json_decode($importDocument->getAttribute('source'), true));
|
||||
|
||||
$destination = new DestinationsAppwrite(
|
||||
$projectDocument->getId(),
|
||||
'http://appwrite/v1',
|
||||
$tempAPIKey['secret'],
|
||||
);
|
||||
|
||||
$transfer = new Transfer(
|
||||
$source,
|
||||
$destination
|
||||
);
|
||||
|
||||
$importDocument->setAttribute('status', 'source-check');
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
$source->report();
|
||||
|
||||
$importDocument->setAttribute('status', 'destination-check');
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
$destination->report();
|
||||
|
||||
/** Start Transfer */
|
||||
$importDocument->setAttribute('status', 'importing');
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
$transfer->run($importDocument->getAttribute('resources'), function () use ($importDocument, $transfer, $projectDocument) {
|
||||
$importDocument->setAttribute('resourceData', json_encode($transfer->getResourceCache()));
|
||||
$importDocument->setAttribute('statusCounters', json_encode($transfer->getStatusCounters()));
|
||||
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
});
|
||||
|
||||
$errors = $transfer->getReport(Resource::STATUS_ERROR);
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$importDocument->setAttribute('status', 'failed');
|
||||
$importDocument->setAttribute('errorData', $errors);
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
return;
|
||||
}
|
||||
|
||||
$importDocument->setAttribute('status', 'completed');
|
||||
$importDocument->setAttribute('stage', 'finished');
|
||||
} catch (\Throwable $th) {
|
||||
Console::error($th->getMessage());
|
||||
|
||||
if ($importDocument) {
|
||||
Console::error($th->getMessage());
|
||||
Console::error($th->getTraceAsString());
|
||||
$importDocument->setAttribute('status', 'failed');
|
||||
$importDocument->setAttribute('errorData', $th->getMessage());
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
if ($importDocument) {
|
||||
$this->updateImportDocument($importDocument, $projectDocument);
|
||||
}
|
||||
if ($tempAPIKey) {
|
||||
$this->removeAPIKey($tempAPIKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Verification
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processVerification(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function shutdown(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Resque\Worker;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Transfer\Destination;
|
||||
use Utopia\Transfer\Destinations\Appwrite as DestinationsAppwrite;
|
||||
use Utopia\Transfer\Progress;
|
||||
use Utopia\Transfer\Source;
|
||||
use Utopia\Transfer\Sources\Appwrite;
|
||||
use Utopia\Transfer\Sources\Firebase;
|
||||
use Utopia\Transfer\Sources\NHost;
|
||||
use Utopia\Transfer\Sources\Supabase;
|
||||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
Console::title('Transfers V1 Worker');
|
||||
Console::success(APP_NAME . ' Transfers worker v1 has started');
|
||||
|
||||
class TransfersV1 extends Worker
|
||||
{
|
||||
/**
|
||||
* Database connection shared across all methods of this file
|
||||
*
|
||||
* @var Database
|
||||
*/
|
||||
private Database $dbForProject;
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return "transfers";
|
||||
}
|
||||
|
||||
public function init(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function run(): void
|
||||
{
|
||||
$this->dbForProject = $this->getProjectDB($this->args['project']['$id']);
|
||||
|
||||
// Process
|
||||
$this->processTransfer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Source
|
||||
*
|
||||
* @return Source
|
||||
* @throws \Exception
|
||||
*/
|
||||
function processSource(): Source
|
||||
{
|
||||
$source = $this->dbForProject->getDocument('sources', $this->args['transfer']['source']);
|
||||
|
||||
$authObject = json_decode($source['data'], true) ?? [];
|
||||
|
||||
switch ($source['type']) {
|
||||
case 'firebase':
|
||||
return new Firebase(
|
||||
$authObject['serviceAccount'] ?? '',
|
||||
Firebase::AUTH_SERVICEACCOUNT
|
||||
);
|
||||
break;
|
||||
case 'supabase':
|
||||
return new Supabase(
|
||||
$authObject['url'] ?? '',
|
||||
$authObject['database'] ?? '',
|
||||
$authObject['username'] ?? '',
|
||||
$authObject['password'] ?? '',
|
||||
$authObject['port'] ?? 5432,
|
||||
);
|
||||
break;
|
||||
case 'nhost':
|
||||
return new NHost(
|
||||
$authObject['url'] ?? '',
|
||||
$authObject['database'] ?? '',
|
||||
$authObject['username'] ?? '',
|
||||
$authObject['password'] ?? '',
|
||||
$authObject['port'] ?? 5432,
|
||||
);
|
||||
break;
|
||||
case 'appwrite':
|
||||
return new Appwrite($authObject['projectId'], $authObject['endpoint'], $authObject['key']);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Invalid source type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Destination
|
||||
*
|
||||
* @return Destination
|
||||
* @throws \Exception
|
||||
*/
|
||||
function processDestination(): Destination
|
||||
{
|
||||
$destination = $this->dbForProject->getDocument('destinations', $this->args['transfer']['destination']);
|
||||
|
||||
$authObject = json_decode($destination['data'], true) ?? [];
|
||||
|
||||
|
||||
switch ($destination['type']) {
|
||||
case 'appwrite':
|
||||
if ($authObject['endpoint'] === 'http://localhost/v1') { // Rewrite into Internal Network.
|
||||
return new DestinationsAppwrite($authObject['projectId'], 'http://appwrite/v1', $authObject['key']);
|
||||
} else {
|
||||
return new DestinationsAppwrite($authObject['projectId'], $authObject['endpoint'], $authObject['key']);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('Invalid destination type');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateAttribute(string $attribute, mixed $value, Document $document): void
|
||||
{
|
||||
$document->setAttribute($attribute, $value);
|
||||
$this->dbForProject->updateDocument($document->getCollection(), $document->getId(), $document);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Transfer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processTransfer(): void
|
||||
{
|
||||
$transferDocument = null;
|
||||
$transfer = null;
|
||||
|
||||
try {
|
||||
$transferDocument = $this->dbForProject->getDocument('transfers', $this->args['transfer']['$id']);
|
||||
$this->updateAttribute('status', 'processing', $transferDocument);
|
||||
|
||||
$source = $this->processSource();
|
||||
$destination = $this->processDestination();
|
||||
|
||||
$transfer = new \Utopia\Transfer\Transfer(
|
||||
$source,
|
||||
$destination
|
||||
);
|
||||
|
||||
$this->updateAttribute('stage', 'source-check', $transferDocument);
|
||||
if (!$source->check()) {
|
||||
$transferDocument->setAttribute('status', 'failed');
|
||||
$transferDocument->setAttribute('errorData', json_encode($transfer->getLogs('error')));
|
||||
}
|
||||
|
||||
$this->updateAttribute('stage', 'destination-check', $transferDocument);
|
||||
if (!$destination->check()) {
|
||||
$transferDocument->setAttribute('status', 'failed');
|
||||
$transferDocument->setAttribute('stage', 'destination-check');
|
||||
$transferDocument->setAttribute('errorData', json_encode($transfer->getLogs('error')));
|
||||
}
|
||||
|
||||
/** Start Transfer */
|
||||
$transfer->run($transferDocument->getAttribute('resources'), function (Progress $progress) use ($transferDocument, $transfer, $source, $destination) {
|
||||
var_dump($progress->getProgress());
|
||||
$transferDocument->setAttribute('stage', 'transfer');
|
||||
$transferDocument->setAttribute('latestProgress', json_encode($progress));
|
||||
$transferDocument->setAttribute('totalProgress', json_encode([
|
||||
'source' => $source->getCounter(),
|
||||
'destination' => $destination->getCounter(),
|
||||
]));
|
||||
$this->dbForProject->updateDocument($transferDocument->getCollection(), $transferDocument->getId(), $transferDocument);
|
||||
});
|
||||
|
||||
if (!empty($transfer->getLogs('error'))) {
|
||||
$transferDocument->setAttribute('status', 'failed');
|
||||
|
||||
$logs = [];
|
||||
|
||||
foreach ($transfer->getLogs('error') as $log) {
|
||||
$logs[] = $log->asArray();
|
||||
}
|
||||
|
||||
var_dump($logs);
|
||||
|
||||
$transferDocument->setAttribute('errorData', json_encode($logs));
|
||||
} else {
|
||||
$transferDocument->setAttribute('status', 'completed');
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
Console::error($th->getMessage());
|
||||
|
||||
// Improve Error Handler.
|
||||
|
||||
if ($transferDocument) {
|
||||
$transferDocument->setAttribute('status', 'failed');
|
||||
|
||||
foreach ($transfer->getLogs('error') as $log) {
|
||||
$logs[] = $log->asArray();
|
||||
}
|
||||
|
||||
var_dump($logs);
|
||||
|
||||
$transferDocument->setAttribute('errorData', json_encode($logs));
|
||||
}
|
||||
|
||||
throw $th;
|
||||
} finally {
|
||||
if ($transferDocument) {
|
||||
$this->dbForProject->updateDocument($transferDocument->getCollection(), $transferDocument->getId(), $transferDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Verification
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processVerification(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function shutdown(): void
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,4 @@ else
|
||||
REDIS_BACKEND="redis://${_APP_REDIS_USER}:${_APP_REDIS_PASS}@${_APP_REDIS_HOST}:${_APP_REDIS_PORT}"
|
||||
fi
|
||||
|
||||
INTERVAL=0.1 QUEUE='v1-transfers' APP_INCLUDE='/usr/src/code/app/workers/transfers.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
INTERVAL=0.1 QUEUE='v1-imports' APP_INCLUDE='/usr/src/code/app/workers/imports.php' php /usr/src/code/vendor/bin/resque -dopcache.preload=opcache.preload=/usr/src/code/app/preload.php
|
||||
+1
-1
@@ -62,7 +62,7 @@
|
||||
"utopia-php/storage": "0.14.*",
|
||||
"utopia-php/swoole": "0.5.*",
|
||||
"utopia-php/websocket": "0.1.*",
|
||||
"utopia-php/transfer": "dev-feat-database-and-documents",
|
||||
"utopia-php/transfer": "dev-feat-initial-push",
|
||||
"resque/php-resque": "1.3.6",
|
||||
"matomo/device-detector": "6.0.*",
|
||||
"dragonmantank/cron-expression": "3.3.1",
|
||||
|
||||
Generated
+89
-97
@@ -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": "a196257ea0952cad0b534301e4e63966",
|
||||
"content-hash": "772c42c6e08002543ddec1c7af0c44e2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -65,16 +65,16 @@
|
||||
},
|
||||
{
|
||||
"name": "appwrite/appwrite",
|
||||
"version": "7.2.0",
|
||||
"version": "8.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-for-php.git",
|
||||
"reference": "8940689d040153f397371a367926e4e97e257f41"
|
||||
"reference": "2b9e966edf35c4061179ed98ea364698ab30de8b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/8940689d040153f397371a367926e4e97e257f41",
|
||||
"reference": "8940689d040153f397371a367926e4e97e257f41",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/2b9e966edf35c4061179ed98ea364698ab30de8b",
|
||||
"reference": "2b9e966edf35c4061179ed98ea364698ab30de8b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -99,10 +99,10 @@
|
||||
"support": {
|
||||
"email": "team@appwrite.io",
|
||||
"issues": "https://github.com/appwrite/sdk-for-php/issues",
|
||||
"source": "https://github.com/appwrite/sdk-for-php/tree/7.2.0",
|
||||
"source": "https://github.com/appwrite/sdk-for-php/tree/8.0.0",
|
||||
"url": "https://appwrite.io/support"
|
||||
},
|
||||
"time": "2022-12-27T22:34:08+00:00"
|
||||
"time": "2023-04-12T10:16:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "appwrite/php-clamav",
|
||||
@@ -341,16 +341,16 @@
|
||||
},
|
||||
{
|
||||
"name": "colinmollenhour/credis",
|
||||
"version": "v1.14.0",
|
||||
"version": "v1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/colinmollenhour/credis.git",
|
||||
"reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc"
|
||||
"reference": "28810439de1d9597b7ba11794ed9479fb6f3de7c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/colinmollenhour/credis/zipball/dccc8a46586475075fbb012d8bd523b8a938c2dc",
|
||||
"reference": "dccc8a46586475075fbb012d8bd523b8a938c2dc",
|
||||
"url": "https://api.github.com/repos/colinmollenhour/credis/zipball/28810439de1d9597b7ba11794ed9479fb6f3de7c",
|
||||
"reference": "28810439de1d9597b7ba11794ed9479fb6f3de7c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -382,9 +382,9 @@
|
||||
"homepage": "https://github.com/colinmollenhour/credis",
|
||||
"support": {
|
||||
"issues": "https://github.com/colinmollenhour/credis/issues",
|
||||
"source": "https://github.com/colinmollenhour/credis/tree/v1.14.0"
|
||||
"source": "https://github.com/colinmollenhour/credis/tree/v1.15.0"
|
||||
},
|
||||
"time": "2022-11-09T01:18:39+00:00"
|
||||
"time": "2023-04-18T15:34:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/package-versions-deprecated",
|
||||
@@ -522,22 +522,22 @@
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.5.0",
|
||||
"version": "7.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba"
|
||||
"reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba",
|
||||
"reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/b964ca597e86b752cd994f27293e9fa6b6a95ed9",
|
||||
"reference": "b964ca597e86b752cd994f27293e9fa6b6a95ed9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.5",
|
||||
"guzzlehttp/psr7": "^1.9 || ^2.4",
|
||||
"guzzlehttp/psr7": "^1.9.1 || ^2.4.5",
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||
@@ -630,7 +630,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.5.0"
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -646,7 +646,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-08-28T15:39:27+00:00"
|
||||
"time": "2023-04-17T16:30:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
@@ -734,22 +734,22 @@
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "2.4.4",
|
||||
"version": "2.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf"
|
||||
"reference": "b635f279edd83fc275f822a1188157ffea568ff6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
|
||||
"reference": "3cf1b6d4f0c820a2cf8bcaec39fc698f3443b5cf",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/b635f279edd83fc275f822a1188157ffea568ff6",
|
||||
"reference": "b635f279edd83fc275f822a1188157ffea568ff6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-message": "^1.1 || ^2.0",
|
||||
"ralouphie/getallheaders": "^3.0"
|
||||
},
|
||||
"provide": {
|
||||
@@ -769,9 +769,6 @@
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -833,7 +830,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/psr7/issues",
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.4.4"
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.5.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -849,7 +846,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-09T13:19:02+00:00"
|
||||
"time": "2023-04-17T16:11:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "influxdb/influxdb-php",
|
||||
@@ -1462,16 +1459,16 @@
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.1",
|
||||
"version": "2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba"
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
|
||||
"reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1480,7 +1477,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -1495,7 +1492,7 @@
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
@@ -1509,9 +1506,9 @@
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-message/tree/1.1"
|
||||
"source": "https://github.com/php-fig/http-message/tree/2.0"
|
||||
},
|
||||
"time": "2023-04-04T09:50:52+00:00"
|
||||
"time": "2023-04-04T09:54:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
@@ -1898,26 +1895,26 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.24.0",
|
||||
"version": "0.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "403641f16a53b81ac40b91111a86e5672da49e8c"
|
||||
"reference": "49a180cab5316cddec9676d900d5112d03e97ffc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/403641f16a53b81ac40b91111a86e5672da49e8c",
|
||||
"reference": "403641f16a53b81ac40b91111a86e5672da49e8c",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/49a180cab5316cddec9676d900d5112d03e97ffc",
|
||||
"reference": "49a180cab5316cddec9676d900d5112d03e97ffc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.35.*"
|
||||
"utopia-php/database": "0.36.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"laravel/pint": "1.5.*",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^9.4"
|
||||
},
|
||||
@@ -1941,9 +1938,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.24.0"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.25.0"
|
||||
},
|
||||
"time": "2023-04-11T05:31:55+00:00"
|
||||
"time": "2023-04-27T15:43:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
@@ -2002,24 +1999,24 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.25.0",
|
||||
"version": "0.26.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "adc209f2e16878e5468f0b9cfd9f7f7ab497db31"
|
||||
"reference": "e7228080f14df28737fbb050c180c26d86ac0403"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/adc209f2e16878e5468f0b9cfd9f7f7ab497db31",
|
||||
"reference": "adc209f2e16878e5468f0b9cfd9f7f7ab497db31",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/e7228080f14df28737fbb050c180c26d86ac0403",
|
||||
"reference": "e7228080f14df28737fbb050c180c26d86ac0403",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.35.*"
|
||||
"utopia-php/database": "0.36.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"laravel/pint": "1.5.*",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
@@ -2043,9 +2040,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.25.0"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.26.0"
|
||||
},
|
||||
"time": "2023-04-11T05:31:15+00:00"
|
||||
"time": "2023-04-27T15:43:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
@@ -2202,16 +2199,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.35.1",
|
||||
"version": "0.36.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "b5ac84e0c77145bd0a7f38718ad915729c64fa93"
|
||||
"reference": "f6ab65e59a199da5155c114564077b1ab8c4daef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/b5ac84e0c77145bd0a7f38718ad915729c64fa93",
|
||||
"reference": "b5ac84e0c77145bd0a7f38718ad915729c64fa93",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/f6ab65e59a199da5155c114564077b1ab8c4daef",
|
||||
"reference": "f6ab65e59a199da5155c114564077b1ab8c4daef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2254,9 +2251,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.35.1"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.36.1"
|
||||
},
|
||||
"time": "2023-04-13T04:30:08+00:00"
|
||||
"time": "2023-04-27T08:39:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
@@ -2943,20 +2940,20 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/transfer",
|
||||
"version": "dev-feat-database-and-documents",
|
||||
"version": "dev-feat-initial-push",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/transfer.git",
|
||||
"reference": "579e02466432d88ba92d70e86553d3e4cc5af867"
|
||||
"reference": "fec14703d80cfe3c2b3a3f1cac79dbecfbdffd36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/transfer/zipball/579e02466432d88ba92d70e86553d3e4cc5af867",
|
||||
"reference": "579e02466432d88ba92d70e86553d3e4cc5af867",
|
||||
"url": "https://api.github.com/repos/utopia-php/transfer/zipball/fec14703d80cfe3c2b3a3f1cac79dbecfbdffd36",
|
||||
"reference": "fec14703d80cfe3c2b3a3f1cac79dbecfbdffd36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"appwrite/appwrite": "^7.2",
|
||||
"appwrite/appwrite": "^8.0",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cli": "^0.13.0"
|
||||
},
|
||||
@@ -2994,10 +2991,10 @@
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/utopia-php/transfer/tree/feat-database-and-documents",
|
||||
"source": "https://github.com/utopia-php/transfer/tree/feat-initial-push",
|
||||
"issues": "https://github.com/utopia-php/transfer/issues"
|
||||
},
|
||||
"time": "2023-04-03T09:31:45+00:00"
|
||||
"time": "2023-05-12T08:22:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
@@ -3185,16 +3182,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.32.2",
|
||||
"version": "0.32.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "cdec289bcf38c99d0074414d2438e9967d0c9699"
|
||||
"reference": "4057e14a61335070034b1cbdce9e39bef94d997d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/cdec289bcf38c99d0074414d2438e9967d0c9699",
|
||||
"reference": "cdec289bcf38c99d0074414d2438e9967d0c9699",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/4057e14a61335070034b1cbdce9e39bef94d997d",
|
||||
"reference": "4057e14a61335070034b1cbdce9e39bef94d997d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3230,9 +3227,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.32.2"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.32.3"
|
||||
},
|
||||
"time": "2023-04-12T21:06:57+00:00"
|
||||
"time": "2023-04-27T19:22:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
@@ -3935,16 +3932,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"version": "1.18.1",
|
||||
"version": "1.20.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||
"reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f"
|
||||
"reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/22dcdfd725ddf99583bfe398fc624ad6c5004a0f",
|
||||
"reference": "22dcdfd725ddf99583bfe398fc624ad6c5004a0f",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd",
|
||||
"reference": "7d568c87a9df9c5f7e8b5f075fc469aa8cb0a4cd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3974,9 +3971,9 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.18.1"
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.20.4"
|
||||
},
|
||||
"time": "2023-04-07T11:51:11+00:00"
|
||||
"time": "2023-05-02T09:19:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -4699,16 +4696,16 @@
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
"version": "4.0.4",
|
||||
"version": "4.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
|
||||
"reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
|
||||
"reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
|
||||
"reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4753,7 +4750,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/diff/issues",
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
|
||||
"source": "https://github.com/sebastianbergmann/diff/tree/4.0.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4761,7 +4758,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2020-10-26T13:10:38+00:00"
|
||||
"time": "2023-05-07T05:35:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
@@ -5728,16 +5725,16 @@
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.5.1",
|
||||
"version": "v3.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15"
|
||||
"reference": "106c170d08e8415d78be2d16c3d057d0d108262b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15",
|
||||
"reference": "a6e0510cc793912b451fd40ab983a1d28f611c15",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/106c170d08e8415d78be2d16c3d057d0d108262b",
|
||||
"reference": "106c170d08e8415d78be2d16c3d057d0d108262b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5746,15 +5743,10 @@
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0",
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.5-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Twig\\": "src/"
|
||||
@@ -5788,7 +5780,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.5.1"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.6.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -5800,7 +5792,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-08T07:49:20+00:00"
|
||||
"time": "2023-05-03T19:06:57+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
||||
+3
-3
@@ -575,10 +575,10 @@ services:
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
appwrite-worker-transfers:
|
||||
entrypoint: worker-transfers
|
||||
appwrite-worker-imports:
|
||||
entrypoint: worker-imports
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-transfers
|
||||
container_name: appwrite-worker-imports
|
||||
restart: unless-stopped
|
||||
image: appwrite-dev
|
||||
networks:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Download a code deployment by its unique ID. The endpoint response returns with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory.
|
||||
@@ -1 +1 @@
|
||||
Get a file content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory.
|
||||
Get a file content by its unique ID. The endpoint response returns with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory.
|
||||
@@ -35,8 +35,8 @@ class Event
|
||||
public const MESSAGING_QUEUE_NAME = 'v1-messaging';
|
||||
public const MESSAGING_CLASS_NAME = 'MessagingV1';
|
||||
|
||||
public const TRANSFER_QUEUE_NAME = 'v1-transfers';
|
||||
public const TRANSFER_CLASS_NAME = 'TransfersV1';
|
||||
public const IMPORTS_QUEUE_NAME = 'v1-imports';
|
||||
public const IMPORTS_CLASS_NAME = 'ImportsV1';
|
||||
|
||||
protected string $queue = '';
|
||||
protected string $class = '';
|
||||
|
||||
@@ -7,41 +7,41 @@ use Resque;
|
||||
use ResqueScheduler;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Transfer extends Event
|
||||
class Import extends Event
|
||||
{
|
||||
protected string $type = '';
|
||||
protected ?Document $transfer = null;
|
||||
protected ?Document $import = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Event::TRANSFER_QUEUE_NAME, Event::TRANSFER_CLASS_NAME);
|
||||
parent::__construct(Event::IMPORTS_QUEUE_NAME, Event::IMPORTS_CLASS_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transfer document for the transfer event.
|
||||
* Sets import document for the import event.
|
||||
*
|
||||
* @param Document $transfer
|
||||
* @param Document $import
|
||||
* @return self
|
||||
*/
|
||||
public function setTransfer(Document $transfer): self
|
||||
public function setImport(Document $import): self
|
||||
{
|
||||
$this->transfer = $transfer;
|
||||
$this->import = $import;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set transfer document for the function event.
|
||||
* Returns set import document for the function event.
|
||||
*
|
||||
* @return null|Document
|
||||
*/
|
||||
public function getTransfer(): ?Document
|
||||
public function getImport(): ?Document
|
||||
{
|
||||
return $this->transfer;
|
||||
return $this->import;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transfer type for the transfer event.
|
||||
* Sets import type for the import event.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
@@ -55,7 +55,7 @@ class Transfer extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set transfer type for the transfer event.
|
||||
* Returns set import type for the import event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -65,7 +65,7 @@ class Transfer extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the transfer event and sends it to the transfers worker.
|
||||
* Executes the import event and sends it to the imports worker.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
@@ -75,12 +75,12 @@ class Transfer extends Event
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'transfer' => $this->transfer
|
||||
'import' => $this->import
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules the transfer event and schedules it in the transfers worker queue.
|
||||
* Schedules the import event and schedules it in the imports worker queue.
|
||||
*
|
||||
* @param \DateTime|int $at
|
||||
* @return void
|
||||
@@ -92,7 +92,7 @@ class Transfer extends Event
|
||||
ResqueScheduler::enqueueAt($at, $this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'transfer' => $this->transfer
|
||||
'import' => $this->import
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class Exception extends \Exception
|
||||
* - Platform
|
||||
* - Domain
|
||||
* - GraphQL
|
||||
* - Transfers
|
||||
* - Imports
|
||||
*/
|
||||
|
||||
/** General */
|
||||
@@ -189,14 +189,10 @@ class Exception extends \Exception
|
||||
public const GRAPHQL_NO_QUERY = 'graphql_no_query';
|
||||
public const GRAPHQL_TOO_MANY_QUERIES = 'graphql_too_many_queries';
|
||||
|
||||
/** Transfers */
|
||||
public const TRANSFER_NOT_FOUND = 'transfer_not_found';
|
||||
public const TRANSFER_ALREADY_EXISTS = 'transfer_already_exists';
|
||||
public const TRANSFER_SOURCE_NOT_FOUND = 'transfer_source_not_found';
|
||||
public const TRANSFER_DESTINATION_NOT_FOUND = 'transfer_destination_not_found';
|
||||
public const TRANSFER_SOURCE_FAILED = 'transfer_source_failed';
|
||||
public const TRANSFER_DESTINATION_FAILED = 'transfer_destination_failed';
|
||||
public const TRANSFER_IN_PROGRESS = 'transfer_in_progress';
|
||||
/** Imports */
|
||||
public const IMPORT_NOT_FOUND = 'import_not_found';
|
||||
public const IMPORT_ALREADY_EXISTS = 'import_already_exists';
|
||||
public const IMPORT_IN_PROGRESS = 'import_in_progress';
|
||||
|
||||
protected $type = '';
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator\Queries;
|
||||
|
||||
class Destinations extends Base
|
||||
{
|
||||
public const ALLOWED_ATTRIBUTES = [
|
||||
'type',
|
||||
'name',
|
||||
'data'
|
||||
];
|
||||
|
||||
/**
|
||||
* Expression constructor
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('destinations', self::ALLOWED_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
+4
-5
@@ -2,16 +2,15 @@
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator\Queries;
|
||||
|
||||
class Transfers extends Base
|
||||
class Imports extends Base
|
||||
{
|
||||
public const ALLOWED_ATTRIBUTES = [
|
||||
'status',
|
||||
'stage',
|
||||
'source',
|
||||
'destination',
|
||||
'resources',
|
||||
'totalProgress',
|
||||
'latestProgress',
|
||||
'statusCounters',
|
||||
'resourceData',
|
||||
'errorData'
|
||||
];
|
||||
|
||||
@@ -21,6 +20,6 @@ class Transfers extends Base
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('transfers', self::ALLOWED_ATTRIBUTES);
|
||||
parent::__construct('imports', self::ALLOWED_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator\Queries;
|
||||
|
||||
class Sources extends Base
|
||||
{
|
||||
public const ALLOWED_ATTRIBUTES = [
|
||||
'type',
|
||||
'name',
|
||||
'data'
|
||||
];
|
||||
|
||||
/**
|
||||
* Expression constructor
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('sources', self::ALLOWED_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
@@ -85,12 +85,8 @@ use Appwrite\Utopia\Response\Model\UsageProject;
|
||||
use Appwrite\Utopia\Response\Model\UsageStorage;
|
||||
use Appwrite\Utopia\Response\Model\UsageUsers;
|
||||
use Appwrite\Utopia\Response\Model\Variable;
|
||||
use Appwrite\Utopia\Response\Model\Transfer;
|
||||
use Appwrite\Utopia\Response\Model\Source;
|
||||
use Appwrite\Utopia\Response\Model\Destination;
|
||||
use Appwrite\Utopia\Response\Model\DestinationValidation;
|
||||
use Appwrite\Utopia\Response\Model\SourceValidation;
|
||||
use Appwrite\Utopia\Response\Model\TransferValidationError;
|
||||
use Appwrite\Utopia\Response\Model\Import;
|
||||
use Appwrite\Utopia\Response\Model\ImportValidationError;
|
||||
|
||||
/**
|
||||
* @method int getStatusCode()
|
||||
@@ -225,16 +221,10 @@ class Response extends SwooleResponse
|
||||
// Console
|
||||
public const MODEL_CONSOLE_VARIABLES = 'consoleVariables';
|
||||
|
||||
// Transfers
|
||||
public const MODEL_TRANSFER = 'transfer';
|
||||
public const MODEL_TRANSFER_LIST = 'transferList';
|
||||
public const MODEL_TRANSFER_VALIDATION_ERROR = 'transferValidationError';
|
||||
public const MODEL_SOURCE = 'source';
|
||||
public const MODEL_SOURCE_LIST = 'sourceList';
|
||||
public const MODEL_SOURCE_VALIDATION = 'sourceValidation';
|
||||
public const MODEL_DESTINATION = 'destination';
|
||||
public const MODEL_DESTINATION_LIST = 'destinationList';
|
||||
public const MODEL_DESTINATION_VALIDATION = 'destinationValidation';
|
||||
// Imports
|
||||
public const MODEL_IMPORT = 'import';
|
||||
public const MODEL_IMPORT_LIST = 'importList';
|
||||
public const MODEL_IMPORT_VALIDATION_ERROR = 'importValidationError';
|
||||
|
||||
// Deprecated
|
||||
public const MODEL_PERMISSIONS = 'permissions';
|
||||
@@ -297,9 +287,7 @@ class Response extends SwooleResponse
|
||||
->setModel(new BaseList('Phones List', self::MODEL_PHONE_LIST, 'phones', self::MODEL_PHONE))
|
||||
->setModel(new BaseList('Metric List', self::MODEL_METRIC_LIST, 'metrics', self::MODEL_METRIC, true, false))
|
||||
->setModel(new BaseList('Variables List', self::MODEL_VARIABLE_LIST, 'variables', self::MODEL_VARIABLE))
|
||||
->setModel(new BaseList('Transfers List', self::MODEL_TRANSFER_LIST, 'transfers', self::MODEL_TRANSFER))
|
||||
->setModel(new BaseList('Sources List', self::MODEL_SOURCE_LIST, 'sources', self::MODEL_SOURCE))
|
||||
->setModel(new BaseList('Destination List', self::MODEL_DESTINATION_LIST, 'destinations', self::MODEL_DESTINATION))
|
||||
->setModel(new BaseList('Imports List', self::MODEL_IMPORT_LIST, 'imports', self::MODEL_IMPORT))
|
||||
// Entities
|
||||
->setModel(new Database())
|
||||
->setModel(new Collection())
|
||||
@@ -369,12 +357,8 @@ class Response extends SwooleResponse
|
||||
->setModel(new UsageFunction())
|
||||
->setModel(new UsageProject())
|
||||
->setModel(new ConsoleVariables())
|
||||
->setModel(new Transfer())
|
||||
->setModel(new Destination())
|
||||
->setModel(new DestinationValidation())
|
||||
->setModel(new Source())
|
||||
->setModel(new SourceValidation())
|
||||
->setModel(new TransferValidationError())
|
||||
->setModel(new Import())
|
||||
->setModel(new ImportValidationError())
|
||||
// Verification
|
||||
// Recovery
|
||||
// Tests (keep last)
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
|
||||
class Destination extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
->addRule('$createdAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Variable creation date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
->addRule('$updatedAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Variable creation date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
->addRule('type', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer type.',
|
||||
'default' => '',
|
||||
'example' => 'appwrite',
|
||||
])
|
||||
->addRule('name', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer name.',
|
||||
'default' => '',
|
||||
'example' => 'Appwrite',
|
||||
])
|
||||
->addRule('lastCheck', [
|
||||
'type' => self::TYPE_JSON,
|
||||
'description' => 'A JSON Object with the result of the last source check.',
|
||||
'default' => '',
|
||||
'example' => [
|
||||
'success' => false,
|
||||
'message' => 'Transfer completed successfully'
|
||||
],
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Destination';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_DESTINATION;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
|
||||
class DestinationValidation extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('success', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'If the validation was successful or not.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('message', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Validation message.',
|
||||
'default' => '',
|
||||
'example' => 'Validation completed successfully',
|
||||
])
|
||||
->addRule('errors', [
|
||||
'type' => Response::MODEL_TRANSFER_VALIDATION_ERROR,
|
||||
'description' => 'A key-value array of all the validation errors.',
|
||||
'default' => [],
|
||||
'example' => [
|
||||
'Users' => ['Access to table "public.users" is denied.'],
|
||||
'Databases' => ['Failed to access database. Please check your connection.'],
|
||||
],
|
||||
'requried' => false
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'DestinationValidation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_DESTINATION_VALIDATION;
|
||||
}
|
||||
}
|
||||
+16
-22
@@ -5,14 +5,14 @@ namespace Appwrite\Utopia\Response\Model;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
|
||||
class Transfer extends Model
|
||||
class Import extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer ID.',
|
||||
'description' => 'Import ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
@@ -30,46 +30,40 @@ class Transfer extends Model
|
||||
])
|
||||
->addRule('status', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer status.',
|
||||
'description' => 'Import status.',
|
||||
'default' => '',
|
||||
'example' => 'pending',
|
||||
])
|
||||
->addRule('stage', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer stage.',
|
||||
'description' => 'Import stage.',
|
||||
'default' => '',
|
||||
'example' => 'init',
|
||||
])
|
||||
->addRule('source', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Source ID.',
|
||||
'description' => 'An object containing the source of the import.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
->addRule('destination', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Destination ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
'example' => '{"type": "Appwrite", "endpoint": "xxxxxxxx", ...}',
|
||||
])
|
||||
->addRule('resources', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Resources to transfer.',
|
||||
'description' => 'Resources to import.',
|
||||
'default' => [],
|
||||
'example' => ['users'],
|
||||
'example' => ['user'],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('totalProgress', [
|
||||
->addRule('statusCounters', [
|
||||
'type' => self::TYPE_JSON,
|
||||
'description' => 'A group of counters that represent the total progress of the transfer.',
|
||||
'description' => 'A group of counters that represent the total progress of the import.',
|
||||
'default' => [],
|
||||
'example' => '{"source":[], "destination": []}',
|
||||
'example' => '{"Database": {"PENDING": 0, "SUCCESS": 1, "ERROR": 0, "SKIP": 0, "PROCESSING": 0, "WARNING": 0}}',
|
||||
])
|
||||
->addRule('latestProgress', [
|
||||
->addRule('resourceData', [
|
||||
'type' => self::TYPE_JSON,
|
||||
'description' => 'The latest progress of the transfer.',
|
||||
'description' => 'An array of objects containing the report data of the resources that were imported.',
|
||||
'default' => [],
|
||||
'example' => '{"source":[], "destination": []}',
|
||||
'example' => '[{"resource":"Database","id":"public","status":"SUCCESS","message":""}]',
|
||||
])
|
||||
->addRule('errorData', [
|
||||
'type' => self::TYPE_JSON,
|
||||
@@ -87,7 +81,7 @@ class Transfer extends Model
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Transfer';
|
||||
return 'Import';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,6 +91,6 @@ class Transfer extends Model
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_TRANSFER;
|
||||
return Response::MODEL_IMPORT;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -4,7 +4,7 @@ namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
|
||||
class TransferValidationError extends Any
|
||||
class ImportValidationError extends Any
|
||||
{
|
||||
/**
|
||||
* Get Name
|
||||
@@ -13,7 +13,7 @@ class TransferValidationError extends Any
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Transfer Validiation Error';
|
||||
return 'Import Validiation Error';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,6 +23,6 @@ class TransferValidationError extends Any
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_TRANSFER_VALIDATION_ERROR;
|
||||
return Response::MODEL_IMPORT_VALIDATION_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
|
||||
class Source extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('$id', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
->addRule('$createdAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Variable creation date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
->addRule('$updatedAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Variable creation date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
->addRule('type', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer type.',
|
||||
'default' => '',
|
||||
'example' => 'appwrite',
|
||||
])
|
||||
->addRule('name', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Transfer name.',
|
||||
'default' => '',
|
||||
'example' => 'Appwrite',
|
||||
])
|
||||
->addRule('lastCheck', [
|
||||
'type' => self::TYPE_JSON,
|
||||
'description' => 'A JSON Object with the result of the last source check.',
|
||||
'default' => '',
|
||||
'example' => [
|
||||
'success' => false,
|
||||
'message' => 'Transfer completed successfully'
|
||||
],
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Source';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_SOURCE;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Response\Model;
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model;
|
||||
|
||||
class SourceValidation extends Model
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->addRule('success', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'If the validation was successful or not.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
])
|
||||
->addRule('message', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Validation message.',
|
||||
'default' => '',
|
||||
'example' => 'Validation completed successfully',
|
||||
])
|
||||
->addRule('errors', [
|
||||
'type' => Response::MODEL_TRANSFER_VALIDATION_ERROR,
|
||||
'description' => 'A key-value array of all the validation errors.',
|
||||
'default' => [],
|
||||
'example' => [
|
||||
'Users' => ['Access to table "public.users" is denied.'],
|
||||
'Documents' => ['Failed to access database. Please check your connection.'],
|
||||
],
|
||||
'requried' => false
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return 'SourceValidation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return Response::MODEL_SOURCE_VALIDATION;
|
||||
}
|
||||
}
|
||||
@@ -81,8 +81,8 @@ trait ProjectCustom
|
||||
'locale.read',
|
||||
'avatars.read',
|
||||
'health.read',
|
||||
'transfers.read',
|
||||
'transfers.write'
|
||||
'imports.read',
|
||||
'imports.write'
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user