mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch 'feat-mailgun-provider' of https://github.com/appwrite/appwrite into feat-topics-controller
This commit is contained in:
@@ -17,14 +17,17 @@ class Exception extends AppwriteException
|
||||
$decoded = json_decode($response, true);
|
||||
if (\is_array($decoded)) {
|
||||
if (\is_array($decoded['error'] ?? '')) {
|
||||
$this->error = $decoded['error']['status'];
|
||||
$this->errorDescription = $decoded['error']['message'];
|
||||
$this->message = $this->error . ': ' . $this->errorDescription;
|
||||
$this->error = $decoded['error']['status'] ?? 'Unknown error';
|
||||
$this->errorDescription = $decoded['error']['message'] ?? 'No description';
|
||||
} elseif (\is_array($decoded['errors'] ?? '')) {
|
||||
$this->error = $decoded['error'] ?? $decoded['message'] ?? 'Unknown error';
|
||||
$this->errorDescription = $decoded['errors'][0]['message'] ?? 'No description';
|
||||
} else {
|
||||
$this->error = $decoded['error'] ?? $decoded['message'] ?? 'Unknown error';
|
||||
$this->errorDescription = $decoded['error_description'] ?? 'No description';
|
||||
$this->message = $this->error . ': ' . $this->errorDescription;
|
||||
}
|
||||
|
||||
$this->message = $this->error . ': ' . $this->errorDescription;
|
||||
}
|
||||
$type = match ($code) {
|
||||
400 => AppwriteException::USER_OAUTH2_BAD_REQUEST,
|
||||
|
||||
@@ -66,6 +66,7 @@ abstract class Migration
|
||||
'1.3.8' => 'V18',
|
||||
'1.4.0' => 'V19',
|
||||
'1.4.1' => 'V19',
|
||||
'1.4.2' => 'V19',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,6 @@ use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class V19 extends Migration
|
||||
{
|
||||
@@ -51,27 +50,37 @@ class V19 extends Migration
|
||||
|
||||
protected function migrateDomains(): void
|
||||
{
|
||||
foreach ($this->documentsIterator('domains') as $domain) {
|
||||
$status = 'created';
|
||||
if ($domain->getAttribute('verification', false)) {
|
||||
$status = 'verified';
|
||||
}
|
||||
if ($this->consoleDB->exists($this->consoleDB->getDefaultDatabase(), 'domains')) {
|
||||
foreach ($this->documentsIterator('domains') as $domain) {
|
||||
$status = 'created';
|
||||
if ($domain->getAttribute('verification', false)) {
|
||||
$status = 'verified';
|
||||
}
|
||||
|
||||
$ruleDocument = new Document([
|
||||
'projectId' => $domain->getAttribute('projectId'),
|
||||
'projectInternalId' => $domain->getAttribute('projectInternalId'),
|
||||
'domain' => $domain->getAttribute('domain'),
|
||||
'resourceType' => 'api',
|
||||
'resourceInternalId' => '',
|
||||
'resourceId' => '',
|
||||
'status' => $status,
|
||||
'certificateId' => $domain->getAttribute('certificateId'),
|
||||
]);
|
||||
$projectId = $domain->getAttribute('projectId');
|
||||
$projectInternalId = $domain->getAttribute('projectInternalId');
|
||||
|
||||
try {
|
||||
$this->consoleDB->createDocument('rules', $ruleDocument);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Error migrating domain {$domain->getAttribute('domain')}: {$th->getMessage()}");
|
||||
if (empty($projectId) || empty($projectInternalId)) {
|
||||
Console::warning("Error migrating domain {$domain->getAttribute('domain')}: Missing projectId or projectInternalId");
|
||||
continue;
|
||||
}
|
||||
|
||||
$ruleDocument = new Document([
|
||||
'projectId' => $domain->getAttribute('projectId'),
|
||||
'projectInternalId' => $domain->getAttribute('projectInternalId'),
|
||||
'domain' => $domain->getAttribute('domain'),
|
||||
'resourceType' => 'api',
|
||||
'resourceInternalId' => '',
|
||||
'resourceId' => '',
|
||||
'status' => $status,
|
||||
'certificateId' => $domain->getAttribute('certificateId'),
|
||||
]);
|
||||
|
||||
try {
|
||||
$this->consoleDB->createDocument('rules', $ruleDocument);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Error migrating domain {$domain->getAttribute('domain')}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,16 +192,23 @@ class V19 extends Migration
|
||||
|
||||
break;
|
||||
case 'builds':
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}");
|
||||
$attributesToCreate = [
|
||||
'size',
|
||||
'deploymentInternalId',
|
||||
'logs',
|
||||
];
|
||||
foreach ($attributesToCreate as $attribute) {
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("$attribute from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'logs');
|
||||
$this->projectDB->renameAttribute($id, 'outputPath', 'path');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'logs' from {$id}: {$th->getMessage()}");
|
||||
Console::warning("'path' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
@@ -202,13 +218,13 @@ class V19 extends Migration
|
||||
try {
|
||||
$this->projectDB->renameAttribute($id, 'log', 'logs');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'errors' from {$id}: {$th->getMessage()}");
|
||||
Console::warning("'logs' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->updateAttribute($id, 'logs', size: 1000000);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'errors' from {$id}: {$th->getMessage()}");
|
||||
Console::warning("'logs' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
@@ -228,7 +244,25 @@ class V19 extends Migration
|
||||
$attributesToCreate = [
|
||||
'resourceInternalId',
|
||||
'buildInternalId',
|
||||
'commands',
|
||||
'type',
|
||||
'installationId',
|
||||
'installationInternalId',
|
||||
'providerRepositoryId',
|
||||
'repositoryId',
|
||||
'repositoryInternalId',
|
||||
'providerRepositoryName',
|
||||
'providerRepositoryOwner',
|
||||
'providerRepositoryUrl',
|
||||
'providerCommitHash',
|
||||
'providerCommitAuthorUrl',
|
||||
'providerCommitAuthor',
|
||||
'providerCommitMessage',
|
||||
'providerCommitUrl',
|
||||
'providerBranch',
|
||||
'providerBranchUrl',
|
||||
'providerRootDirectory',
|
||||
'providerCommentId',
|
||||
];
|
||||
foreach ($attributesToCreate as $attribute) {
|
||||
try {
|
||||
@@ -270,16 +304,31 @@ class V19 extends Migration
|
||||
|
||||
break;
|
||||
case 'executions':
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'functionInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'functionInternalId' from {$id}: {$th->getMessage()}");
|
||||
$attributesToCreate = [
|
||||
'functionInternalId',
|
||||
'deploymentInternalId',
|
||||
'requestMethod',
|
||||
'requestPath',
|
||||
'requestHeaders',
|
||||
'responseHeaders',
|
||||
];
|
||||
foreach ($attributesToCreate as $attribute) {
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("$attribute from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}");
|
||||
$attributesToDelete = [
|
||||
'response'
|
||||
];
|
||||
foreach ($attributesToDelete as $attribute) {
|
||||
try {
|
||||
$this->projectDB->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'$attribute' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -300,6 +349,18 @@ class V19 extends Migration
|
||||
Console::warning("'responseStatusCode' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->deleteIndex($id, '_key_statusCode');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_statusCode' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_responseStatusCode');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_responseStatusCode' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
|
||||
break;
|
||||
@@ -343,11 +404,13 @@ class V19 extends Migration
|
||||
'providerSilentMode',
|
||||
'logging',
|
||||
'deploymentInternalId',
|
||||
'schedule',
|
||||
'scheduleInternalId',
|
||||
'scheduleId',
|
||||
'version',
|
||||
'entrypoint',
|
||||
'commands',
|
||||
'varsProject'
|
||||
];
|
||||
foreach ($attributesToCreate as $attribute) {
|
||||
try {
|
||||
@@ -558,6 +621,25 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
private function getFunctionCommands(Document $function): string
|
||||
{
|
||||
$runtime = $function->getAttribute('runtime');
|
||||
$language = explode('-', $runtime)[0];
|
||||
$commands = match ($language) {
|
||||
'dart' => 'dart pub get',
|
||||
'deno' => 'deno cache ' . $function->getAttribute('entrypoint'),
|
||||
'dotnet' => 'dotnet restore',
|
||||
'node' => 'npm install',
|
||||
'php' => 'composer install',
|
||||
'python' => 'pip install -r requirements.txt',
|
||||
'ruby' => 'bundle install',
|
||||
'swift' => 'swift package resolve',
|
||||
default => '',
|
||||
};
|
||||
|
||||
return $commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix run on each document
|
||||
*
|
||||
@@ -569,9 +651,9 @@ class V19 extends Migration
|
||||
switch ($document->getCollection()) {
|
||||
case 'attributes':
|
||||
case 'indexes':
|
||||
$status = $document->getAttribute('status', '');
|
||||
$status = $document->getAttribute('status');
|
||||
if ($status === 'failed') {
|
||||
$document->setAttribute('error', 'Unknown problem');
|
||||
$document->setAttribute('error', $document->getAttribute('error', 'Unknown problem'));
|
||||
}
|
||||
break;
|
||||
case 'builds':
|
||||
@@ -581,10 +663,10 @@ class V19 extends Migration
|
||||
|
||||
$stdout = $document->getAttribute('stdout', '');
|
||||
$stderr = $document->getAttribute('stderr', '');
|
||||
$document->setAttribute('logs', $stdout . PHP_EOL . $stderr);
|
||||
$document->setAttribute('logs', $document->getAttribute('logs', $stdout . PHP_EOL . $stderr));
|
||||
break;
|
||||
case 'databases':
|
||||
$document->setAttribute('enabled', true);
|
||||
$document->setAttribute('enabled', $document->getAttribute('enabled', true));
|
||||
break;
|
||||
case 'deployments':
|
||||
$resourceId = $document->getAttribute('resourceId');
|
||||
@@ -597,7 +679,9 @@ class V19 extends Migration
|
||||
$document->setAttribute('buildInternalId', $build->getInternalId());
|
||||
}
|
||||
|
||||
$document->setAttribute('type', 'manual');
|
||||
$commands = $this->getFunctionCommands($function);
|
||||
$document->setAttribute('commands', $document->getAttribute('commands', $commands));
|
||||
$document->setAttribute('type', $document->getAttribute('type', 'manual'));
|
||||
break;
|
||||
case 'executions':
|
||||
$functionId = $document->getAttribute('functionId');
|
||||
@@ -609,9 +693,9 @@ class V19 extends Migration
|
||||
$document->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
break;
|
||||
case 'functions':
|
||||
$document->setAttribute('live', true);
|
||||
$document->setAttribute('logging', true);
|
||||
$document->setAttribute('version', 'v2');
|
||||
$document->setAttribute('live', $document->getAttribute('live', true));
|
||||
$document->setAttribute('logging', $document->getAttribute('logging', true));
|
||||
$document->setAttribute('version', $document->getAttribute('version', 'v2'));
|
||||
$deploymentId = $document->getAttribute('deployment');
|
||||
|
||||
if (!empty($deploymentId)) {
|
||||
@@ -620,19 +704,25 @@ class V19 extends Migration
|
||||
$document->setAttribute('entrypoint', $deployment->getAttribute('entrypoint'));
|
||||
}
|
||||
|
||||
$schedule = $this->consoleDB->createDocument('schedules', new Document([
|
||||
'region' => App::getEnv('_APP_REGION', 'default'), // Todo replace with projects region
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $document->getId(),
|
||||
'resourceInternalId' => $document->getInternalId(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $this->project->getId(),
|
||||
'schedule' => $document->getAttribute('schedule'),
|
||||
'active' => !empty($document->getAttribute('schedule')) && !empty($document->getAttribute('deployment')),
|
||||
]));
|
||||
$commands = $this->getFunctionCommands($document);
|
||||
$document->setAttribute('commands', $document->getAttribute('commands', $commands));
|
||||
|
||||
if (empty($document->getAttribute('scheduleId', null))) {
|
||||
$schedule = $this->consoleDB->createDocument('schedules', new Document([
|
||||
'region' => App::getEnv('_APP_REGION', 'default'), // Todo replace with projects region
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $document->getId(),
|
||||
'resourceInternalId' => $document->getInternalId(),
|
||||
'resourceUpdatedAt' => DateTime::now(),
|
||||
'projectId' => $this->project->getId(),
|
||||
'schedule' => $document->getAttribute('schedule'),
|
||||
'active' => !empty($document->getAttribute('schedule')) && !empty($document->getAttribute('deployment')),
|
||||
]));
|
||||
|
||||
$document->setAttribute('scheduleId', $schedule->getId());
|
||||
$document->setAttribute('scheduleInternalId', $schedule->getInternalId());
|
||||
}
|
||||
|
||||
$document->setAttribute('scheduleId', $schedule->getId());
|
||||
$document->setAttribute('scheduleInternalId', $schedule->getInternalId());
|
||||
break;
|
||||
case 'projects':
|
||||
$document->setAttribute('version', '1.4.0');
|
||||
@@ -640,10 +730,13 @@ class V19 extends Migration
|
||||
$databases = Config::getParam('pools-database', []);
|
||||
$database = $databases[0];
|
||||
|
||||
$document->setAttribute('database', $database);
|
||||
$document->setAttribute('smtp', []);
|
||||
$document->setAttribute('templates', []);
|
||||
$document->setAttribute('database', $document->getAttribute('database', $database));
|
||||
$document->setAttribute('smtp', $document->getAttribute('smtp', []));
|
||||
$document->setAttribute('templates', $document->getAttribute('templates', []));
|
||||
|
||||
break;
|
||||
case 'variables':
|
||||
$document->setAttribute('resourceType', $document->getAttribute('resourceType', 'function'));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -662,14 +755,6 @@ class V19 extends Migration
|
||||
|
||||
$this->projectDB->deleteCachedCollection('projects');
|
||||
|
||||
try {
|
||||
$this->projectDB->deleteAttribute('functions', 'schedule');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'schedule' from functions: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection('functions');
|
||||
|
||||
try {
|
||||
$this->projectDB->deleteAttribute('builds', 'stderr');
|
||||
} catch (\Throwable $th) {
|
||||
@@ -684,4 +769,54 @@ class V19 extends Migration
|
||||
|
||||
$this->projectDB->deleteCachedCollection('builds');
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite parent to skip cache collection as well
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public function forEachDocument(callable $callback): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
|
||||
$collections = match ($internalProjectId) {
|
||||
'console' => $this->collections['console'],
|
||||
default => $this->collections['projects'],
|
||||
};
|
||||
|
||||
foreach ($collections as $collection) {
|
||||
// Also skip cache collection because the we don't need to migrate
|
||||
// it and the $ids cause issues with the cursor pagination
|
||||
if ($collection['$collection'] !== Database::METADATA || $collection['$id'] === 'cache') {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::log('Migrating Collection ' . $collection['$id'] . ':');
|
||||
|
||||
\Co\run(function (array $collection, callable $callback) {
|
||||
foreach ($this->documentsIterator($collection['$id']) as $document) {
|
||||
go(function (Document $document, callable $callback) {
|
||||
if (empty($document->getId()) || empty($document->getCollection())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$old = $document->getArrayCopy();
|
||||
$new = call_user_func($callback, $document);
|
||||
|
||||
if (is_null($new) || $new->getArrayCopy() == $old) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->updateDocument($document->getCollection(), $document->getId(), $document);
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Failed to update document: ' . $th->getMessage());
|
||||
return;
|
||||
}
|
||||
}, $document, $callback);
|
||||
}
|
||||
}, $collection, $callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ class Install extends Action
|
||||
$config = Config::getParam('variables');
|
||||
$defaultHTTPPort = '80';
|
||||
$defaultHTTPSPort = '443';
|
||||
/** @var array<string, array<string, string>> $vars array whre key is variable name and value is variable */
|
||||
$vars = [];
|
||||
|
||||
/**
|
||||
@@ -50,7 +51,7 @@ class Install extends Action
|
||||
|
||||
foreach ($config as $category) {
|
||||
foreach ($category['variables'] ?? [] as $var) {
|
||||
$vars[] = $var;
|
||||
$vars[$var['name']] = $var;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +71,7 @@ class Install extends Action
|
||||
if ($interactive == 'Y' && Console::isInteractive()) {
|
||||
$answer = Console::confirm('Previous installation found, do you want to overwrite it (a backup will be created before overwriting)? (Y/n)');
|
||||
|
||||
if ($answer !== 'Y') {
|
||||
if (\strtolower($answer) !== 'y') {
|
||||
Console::info('No action taken.');
|
||||
return;
|
||||
}
|
||||
@@ -104,10 +105,10 @@ class Install extends Action
|
||||
if (is_null($value)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($vars as $i => $var) {
|
||||
if ($var['name'] === $key) {
|
||||
$vars[$i]['default'] = $value;
|
||||
}
|
||||
|
||||
$configVar = $vars[$key] ?? [];
|
||||
if (!empty($configVar) && !($configVar['overwrite'] ?? false)) {
|
||||
$vars[$key]['default'] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,10 +124,10 @@ class Install extends Action
|
||||
if (is_null($value)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($vars as $i => $var) {
|
||||
if ($var['name'] === $key) {
|
||||
$vars[$i]['default'] = $value;
|
||||
}
|
||||
|
||||
$configVar = $vars[$key] ?? [];
|
||||
if (!empty($configVar) && !($configVar['overwrite'] ?? false)) {
|
||||
$vars[$key]['default'] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +216,8 @@ class Schedule extends Action
|
||||
$functions
|
||||
->setType('schedule')
|
||||
->setFunction($schedule['function'])
|
||||
->setMethod('POST')
|
||||
->setPath('/')
|
||||
->setProject($schedule['project'])
|
||||
->trigger();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class V16 extends Filter
|
||||
$content['commands'] = $this->getCommands($content['runtime'] ?? '');
|
||||
break;
|
||||
case 'functions.createExecution':
|
||||
$content['body'] = $content['data'];
|
||||
$content['body'] = $content['data'] ?? '';
|
||||
unset($content['data']);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8,11 +8,6 @@ use Utopia\Database\DateTime;
|
||||
|
||||
class Message extends Any
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected bool $public = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -30,14 +25,14 @@ class Message extends Any
|
||||
])
|
||||
->addRule('to', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Recipient of message.',
|
||||
'description' => 'Message recipients.',
|
||||
'default' => '',
|
||||
'array' => true,
|
||||
'example' => ['user-1'],
|
||||
])
|
||||
->addRule('deliveryTime', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Recipient of message.',
|
||||
'description' => 'Time the message is delivered at.',
|
||||
'required' => false,
|
||||
'default' => DateTime::now(),
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
@@ -48,7 +43,7 @@ class Message extends Any
|
||||
'required' => false,
|
||||
'default' => '',
|
||||
'array' => true,
|
||||
'example' => 'Credentials not valid.',
|
||||
'example' => ['Failed to send message to target 5e5ea5c16897e: Credentials not valid.'],
|
||||
])
|
||||
->addRule('deliveredTo', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
@@ -56,11 +51,11 @@ class Message extends Any
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
])
|
||||
->addRule('delivered', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
->addRule('status', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Status of delivery.',
|
||||
'default' => false,
|
||||
'example' => true,
|
||||
'default' => 'processing',
|
||||
'example' => 'Message status can be one of the following: processing, sent, failed.',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ use Appwrite\Utopia\Response\Model;
|
||||
|
||||
class Provider extends Model
|
||||
{
|
||||
protected bool $public = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
|
||||
Reference in New Issue
Block a user