mirror of
https://github.com/appwrite/appwrite
synced 2026-05-20 23:48:23 +00:00
Merge pull request #3737 from appwrite/feat-additional-compression-support
Expose and introduce File Compression support
This commit is contained in:
commit
07b62cfbd3
20 changed files with 418 additions and 539 deletions
18
Dockerfile
18
Dockerfile
|
|
@ -34,7 +34,8 @@ ENV PHP_REDIS_VERSION=5.3.7 \
|
|||
PHP_SWOOLE_VERSION=v4.8.10 \
|
||||
PHP_IMAGICK_VERSION=3.7.0 \
|
||||
PHP_YAML_VERSION=2.2.2 \
|
||||
PHP_MAXMINDDB_VERSION=v1.11.0
|
||||
PHP_MAXMINDDB_VERSION=v1.11.0 \
|
||||
PHP_ZSTD_VERSION="4504e4186e79b197cfcb75d4d09aa47ef7d92fe9 "
|
||||
|
||||
RUN \
|
||||
apk add --no-cache --virtual .deps \
|
||||
|
|
@ -50,7 +51,8 @@ RUN \
|
|||
yaml-dev \
|
||||
imagemagick \
|
||||
imagemagick-dev \
|
||||
libmaxminddb-dev
|
||||
libmaxminddb-dev \
|
||||
zstd-dev
|
||||
|
||||
RUN docker-php-ext-install sockets
|
||||
|
||||
|
|
@ -123,6 +125,16 @@ RUN \
|
|||
./configure && \
|
||||
make && make install
|
||||
|
||||
# Zstd Compression
|
||||
FROM compile as zstd
|
||||
RUN git clone --recursive -n https://github.com/kjdev/php-ext-zstd.git \
|
||||
&& cd php-ext-zstd \
|
||||
&& git checkout $PHP_ZSTD_VERSION \
|
||||
&& phpize \
|
||||
&& ./configure --with-libzstd \
|
||||
&& make && make install
|
||||
|
||||
|
||||
# Rust Extensions Compile Image
|
||||
FROM php:8.0.18-cli as rust_compile
|
||||
|
||||
|
|
@ -293,6 +305,7 @@ COPY --from=yaml /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so
|
|||
COPY --from=maxmind /usr/local/lib/php/extensions/no-debug-non-zts-20200930/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=mongodb /usr/local/lib/php/extensions/no-debug-non-zts-20200930/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=scrypt /usr/local/lib/php/extensions/php-scrypt/target/libphp_scrypt.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=zstd /usr/local/lib/php/extensions/no-debug-non-zts-20200930/zstd.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
|
||||
# Add Source Code
|
||||
COPY ./app /usr/src/code/app
|
||||
|
|
@ -350,6 +363,7 @@ RUN echo extension=imagick.so >> /usr/local/etc/php/conf.d/imagick.ini
|
|||
RUN echo extension=yaml.so >> /usr/local/etc/php/conf.d/yaml.ini
|
||||
RUN echo extension=maxminddb.so >> /usr/local/etc/php/conf.d/maxminddb.ini
|
||||
RUN echo extension=libphp_scrypt.so >> /usr/local/etc/php/conf.d/libphp_scrypt.ini
|
||||
RUN echo extension=zstd.so >> /usr/local/etc/php/conf.d/zstd.ini
|
||||
RUN if [ "$DEBUG" == "true" ]; then printf "zend_extension=yasd \nyasd.debug_mode=remote \nyasd.init_file=/usr/local/dev/yasd_init.php \nyasd.remote_port=9005 \nyasd.log_level=-1" >> /usr/local/etc/php/conf.d/yasd.ini; fi
|
||||
|
||||
RUN if [ "$DEBUG" == "true" ]; then echo "opcache.enable=0" >> /usr/local/etc/php/conf.d/appwrite.ini; fi
|
||||
|
|
|
|||
|
|
@ -2875,6 +2875,16 @@ $collections = [
|
|||
'required' => true,
|
||||
'array' => true,
|
||||
],
|
||||
[
|
||||
'$id' => 'compression',
|
||||
'type' => Database::VAR_STRING,
|
||||
'signed' => true,
|
||||
'size' => 10,
|
||||
'format' => '',
|
||||
'filters' => [],
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('encryption'),
|
||||
'type' => Database::VAR_BOOLEAN,
|
||||
|
|
|
|||
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
|
|
@ -6,7 +6,6 @@ use Appwrite\Event\Delete;
|
|||
use Appwrite\Event\Event;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\Usage\Stats;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Config\Config;
|
||||
|
|
@ -29,8 +28,8 @@ use Appwrite\Utopia\Database\Validator\Queries\Buckets;
|
|||
use Appwrite\Utopia\Database\Validator\Queries\Files;
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\Storage\Compression\Algorithms\GZIP;
|
||||
use Utopia\Storage\Compression\Algorithms\Zstd;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\Storage\Validator\File;
|
||||
use Utopia\Storage\Validator\FileExt;
|
||||
|
|
@ -39,7 +38,6 @@ use Utopia\Storage\Validator\Upload;
|
|||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\HexColor;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
|
@ -66,12 +64,13 @@ App::post('/v1/storage/buckets')
|
|||
->param('enabled', true, new Boolean(true), 'Is bucket enabled?', true)
|
||||
->param('maximumFileSize', (int) App::getEnv('_APP_STORAGE_LIMIT', 0), new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '. For self-hosted setups you can change the max limit by changing the `_APP_STORAGE_LIMIT` environment variable. [Learn more about storage environment variables](docs/environment-variables#storage)', true)
|
||||
->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true)
|
||||
->param('compression', 'none', new WhiteList([COMPRESSION_TYPE_NONE, COMPRESSION_TYPE_GZIP, COMPRESSION_TYPE_ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true)
|
||||
->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true)
|
||||
->param('antivirus', true, new Boolean(true), 'Is virus scanning enabled? For file size above ' . Storage::human(APP_LIMIT_ANTIVIRUS, 0) . ' AntiVirus scanning is skipped even if it\'s enabled', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $bucketId, string $name, ?array $permissions, bool $fileSecurity, bool $enabled, int $maximumFileSize, array $allowedFileExtensions, bool $encryption, bool $antivirus, Response $response, Database $dbForProject, Event $events) {
|
||||
->action(function (string $bucketId, string $name, ?array $permissions, bool $fileSecurity, bool $enabled, int $maximumFileSize, array $allowedFileExtensions, string $compression, bool $encryption, bool $antivirus, Response $response, Database $dbForProject, Event $events) {
|
||||
|
||||
$bucketId = $bucketId === 'unique()' ? ID::unique() : $bucketId;
|
||||
|
||||
|
|
@ -120,6 +119,7 @@ App::post('/v1/storage/buckets')
|
|||
'allowedFileExtensions' => $allowedFileExtensions,
|
||||
'fileSecurity' => $fileSecurity,
|
||||
'enabled' => $enabled,
|
||||
'compression' => $compression,
|
||||
'encryption' => $encryption,
|
||||
'antivirus' => $antivirus,
|
||||
'search' => implode(' ', [$bucketId, $name]),
|
||||
|
|
@ -234,12 +234,13 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
->param('enabled', true, new Boolean(true), 'Is bucket enabled?', true)
|
||||
->param('maximumFileSize', null, new Range(1, (int) App::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human((int)App::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '. For self hosted version you can change the limit by changing _APP_STORAGE_LIMIT environment variable. [Learn more about storage environment variables](docs/environment-variables#storage)', true)
|
||||
->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true)
|
||||
->param('compression', 'none', new WhiteList([COMPRESSION_TYPE_NONE, COMPRESSION_TYPE_GZIP, COMPRESSION_TYPE_ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true)
|
||||
->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true)
|
||||
->param('antivirus', true, new Boolean(true), 'Is virus scanning enabled? For file size above ' . Storage::human(APP_LIMIT_ANTIVIRUS, 0) . ' AntiVirus scanning is skipped even if it\'s enabled', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('events')
|
||||
->action(function (string $bucketId, string $name, ?array $permissions, bool $fileSecurity, bool $enabled, ?int $maximumFileSize, array $allowedFileExtensions, bool $encryption, bool $antivirus, Response $response, Database $dbForProject, Event $events) {
|
||||
->action(function (string $bucketId, string $name, ?array $permissions, bool $fileSecurity, bool $enabled, ?int $maximumFileSize, array $allowedFileExtensions, string $compression, bool $encryption, bool $antivirus, Response $response, Database $dbForProject, Event $events) {
|
||||
$bucket = $dbForProject->getDocument('buckets', $bucketId);
|
||||
|
||||
if ($bucket->isEmpty()) {
|
||||
|
|
@ -268,6 +269,7 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
->setAttribute('fileSecurity', $fileSecurity)
|
||||
->setAttribute('enabled', $enabled)
|
||||
->setAttribute('encryption', $encryption)
|
||||
->setAttribute('compression', $compression)
|
||||
->setAttribute('antivirus', $antivirus));
|
||||
|
||||
$events
|
||||
|
|
@ -502,9 +504,18 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
$mimeType = $deviceFiles->getFileMimeType($path); // Get mime-type before compression and encryption
|
||||
$data = '';
|
||||
// Compression
|
||||
if ($fileSize <= APP_STORAGE_READ_BUFFER) {
|
||||
$algorithm = $bucket->getAttribute('compression', 'none');
|
||||
if ($fileSize <= APP_STORAGE_READ_BUFFER && $algorithm != 'none') {
|
||||
$data = $deviceFiles->read($path);
|
||||
$compressor = new GZIP();
|
||||
switch ($algorithm) {
|
||||
case 'zstd':
|
||||
$compressor = new Zstd();
|
||||
break;
|
||||
case 'gzip':
|
||||
default:
|
||||
$compressor = new GZIP();
|
||||
break;
|
||||
}
|
||||
$data = $compressor->compress($data);
|
||||
}
|
||||
|
||||
|
|
@ -524,8 +535,6 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
}
|
||||
|
||||
$sizeActual = $deviceFiles->getFileSize($path);
|
||||
|
||||
$algorithm = empty($compressor) ? '' : $compressor->getName();
|
||||
$fileHash = $deviceFiles->getFileHash($path);
|
||||
|
||||
if ($bucket->getAttribute('encryption', true) && $fileSize <= APP_STORAGE_READ_BUFFER) {
|
||||
|
|
@ -840,7 +849,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
|||
|
||||
$path = $file->getAttribute('path');
|
||||
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
|
||||
$algorithm = $file->getAttribute('algorithm');
|
||||
$algorithm = $file->getAttribute('algorithm', 'none');
|
||||
$cipher = $file->getAttribute('openSSLCipher');
|
||||
$mime = $file->getAttribute('mimeType');
|
||||
if (!\in_array($mime, $inputs) || $file->getAttribute('sizeActual') > (int) App::getEnv('_APP_STORAGE_PREVIEW_LIMIT', 20000000)) {
|
||||
|
|
@ -851,16 +860,13 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
|||
$path = $fileLogos['default_image'];
|
||||
}
|
||||
|
||||
$algorithm = null;
|
||||
$algorithm = 'none';
|
||||
$cipher = null;
|
||||
$background = (empty($background)) ? 'eceff1' : $background;
|
||||
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
|
||||
$deviceFiles = $deviceLocal;
|
||||
}
|
||||
|
||||
|
||||
$compressor = new GZIP();
|
||||
|
||||
if (!$deviceFiles->exists($path)) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
}
|
||||
|
|
@ -885,8 +891,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
|||
);
|
||||
}
|
||||
|
||||
if (!empty($algorithm)) {
|
||||
$source = $compressor->decompress($source);
|
||||
switch ($algorithm) {
|
||||
case 'zstd':
|
||||
$compressor = new Zstd();
|
||||
$source = $compressor->decompress($source);
|
||||
break;
|
||||
case 'gzip':
|
||||
$compressor = new GZIP();
|
||||
$source = $compressor->decompress($source);
|
||||
break;
|
||||
}
|
||||
|
||||
$image = new Image($source);
|
||||
|
|
@ -1021,12 +1034,21 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
|
|||
);
|
||||
}
|
||||
|
||||
if (!empty($file->getAttribute('algorithm', ''))) {
|
||||
if (empty($source)) {
|
||||
$source = $deviceFiles->read($path);
|
||||
}
|
||||
$compressor = new GZIP();
|
||||
$source = $compressor->decompress($source);
|
||||
switch ($file->getAttribute('algorithm', 'none')) {
|
||||
case 'zstd':
|
||||
if (empty($source)) {
|
||||
$source = $deviceFiles->read($path);
|
||||
}
|
||||
$compressor = new Zstd();
|
||||
$source = $compressor->decompress($source);
|
||||
break;
|
||||
case 'gzip':
|
||||
if (empty($source)) {
|
||||
$source = $deviceFiles->read($path);
|
||||
}
|
||||
$compressor = new GZIP();
|
||||
$source = $compressor->decompress($source);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!empty($source)) {
|
||||
|
|
@ -1162,12 +1184,21 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
|
|||
);
|
||||
}
|
||||
|
||||
if (!empty($file->getAttribute('algorithm', ''))) {
|
||||
if (empty($source)) {
|
||||
$source = $deviceFiles->read($path);
|
||||
}
|
||||
$compressor = new GZIP();
|
||||
$source = $compressor->decompress($source);
|
||||
switch ($file->getAttribute('algorithm', 'none')) {
|
||||
case 'zstd':
|
||||
if (empty($source)) {
|
||||
$source = $deviceFiles->read($path);
|
||||
}
|
||||
$compressor = new Zstd();
|
||||
$source = $compressor->decompress($source);
|
||||
break;
|
||||
case 'gzip':
|
||||
if (empty($source)) {
|
||||
$source = $deviceFiles->read($path);
|
||||
}
|
||||
$compressor = new GZIP();
|
||||
$source = $compressor->decompress($source);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!empty($source)) {
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
'maximumFileSize' => (int) App::getEnv('_APP_STORAGE_LIMIT', 0), // 10MB
|
||||
'allowedFileExtensions' => [],
|
||||
'enabled' => true,
|
||||
'compression' => 'gzip',
|
||||
'encryption' => true,
|
||||
'antivirus' => true,
|
||||
'fileSecurity' => true,
|
||||
|
|
|
|||
|
|
@ -151,6 +151,10 @@ const DELETE_TYPE_BUCKETS = 'buckets';
|
|||
const DELETE_TYPE_SESSIONS = 'sessions';
|
||||
const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp';
|
||||
const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource';
|
||||
// Compression type
|
||||
const COMPRESSION_TYPE_NONE = 'none';
|
||||
const COMPRESSION_TYPE_GZIP = 'gzip';
|
||||
const COMPRESSION_TYPE_ZSTD = 'zstd';
|
||||
// Mail Types
|
||||
const MAIL_TYPE_VERIFICATION = 'verification';
|
||||
const MAIL_TYPE_MAGIC_SESSION = 'magicSession';
|
||||
|
|
|
|||
|
|
@ -416,6 +416,13 @@ $fileUpdatePermissions = $this->getParam('fileUpdatePermissions', null);
|
|||
<label for="bucket-maximum-file-size">Maximum File Size (bytes) <span class="tooltip small" data-tooltip="Limit file size allowed in the bucket."><i class="icon-info-circled"></i></span></label>
|
||||
<input name="maximumFileSize" id="bucket-maximum-file-size" type="number" autocomplete="off" data-ls-bind="{{project-bucket.maximumFileSize}}" min="1" data-cast-to="integer" />
|
||||
|
||||
<label for="compression">Compression</label>
|
||||
<select id="compression" data-ls-bind="{{project-bucket.compression}}" name="compression">
|
||||
<option value="none">None</option>
|
||||
<option value="gzip">Gzip</option>
|
||||
<option value="zstd">Zstd</option>
|
||||
</select>
|
||||
|
||||
<div class="margin-bottom">
|
||||
<input name="enabled" type="hidden" data-forms-switch data-cast-to="boolean" data-ls-bind="{{project-bucket.enabled}}" /> Enabled <span class="tooltip" data-tooltip="Mark whether bucket is enabled"><i class="icon-info-circled"></i></span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/domains": "1.1.*",
|
||||
"utopia-php/swoole": "0.3.*",
|
||||
"utopia-php/storage": "0.9.*",
|
||||
"utopia-php/storage": "0.11.*",
|
||||
"utopia-php/websocket": "0.1.0",
|
||||
"utopia-php/image": "0.5.*",
|
||||
"utopia-php/orchestration": "0.6.*",
|
||||
|
|
|
|||
27
composer.lock
generated
27
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "039de21eff3a27955696a9f6f645c548",
|
||||
"content-hash": "7c41d4bcb13c34e72039e3de7e84f732",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -2556,19 +2556,22 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.9.0",
|
||||
"version": "0.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "c7912481a56e17cc86358fa8de57309de5e88ef7"
|
||||
"reference": "59802cf281d1976560cf6e353f250a9b870efddc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/c7912481a56e17cc86358fa8de57309de5e88ef7",
|
||||
"reference": "c7912481a56e17cc86358fa8de57309de5e88ef7",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/59802cf281d1976560cf6e353f250a9b870efddc",
|
||||
"reference": "59802cf281d1976560cf6e353f250a9b870efddc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"ext-zlib": "*",
|
||||
"ext-zstd": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/framework": "0.*.*"
|
||||
},
|
||||
|
|
@ -2602,9 +2605,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.9.0"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.11.0"
|
||||
},
|
||||
"time": "2022-05-19T11:05:45+00:00"
|
||||
"time": "2022-08-31T09:17:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
|
|
@ -2841,12 +2844,12 @@
|
|||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "6e630a62f522ac68a7056bebf81cd032c7a053ba"
|
||||
"reference": "532d4d15ec8f11539972f2848c2e230c49b24f65"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/6e630a62f522ac68a7056bebf81cd032c7a053ba",
|
||||
"reference": "6e630a62f522ac68a7056bebf81cd032c7a053ba",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/532d4d15ec8f11539972f2848c2e230c49b24f65",
|
||||
"reference": "532d4d15ec8f11539972f2848c2e230c49b24f65",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2883,7 +2886,7 @@
|
|||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/feat-new-headers"
|
||||
},
|
||||
"time": "2022-08-29T10:43:33+00:00"
|
||||
"time": "2022-08-20T07:42:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
|
|
@ -5383,5 +5386,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.0"
|
||||
},
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
|
|||
135
public/dist/scripts/app-all.js
vendored
135
public/dist/scripts/app-all.js
vendored
File diff suppressed because one or more lines are too long
133
public/dist/scripts/app-dep.js
vendored
133
public/dist/scripts/app-dep.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/scripts/app.js
vendored
2
public/dist/scripts/app.js
vendored
|
|
@ -522,7 +522,7 @@ return new Promise(function(resolve,reject){let request=new XMLHttpRequest(),key
|
|||
request.onload=function(){if(4===request.readyState&&399>=request.status){let data=request.response;let contentType=this.getResponseHeader('content-type');contentType=contentType.substring(0,contentType.indexOf(';'));switch(contentType){case'application/json':data=JSON.parse(data);break;}
|
||||
resolve(data);}else{reject(new Error(request.statusText));}};if(progress){request.addEventListener('progress',progress);request.upload.addEventListener('progress',progress,false);}
|
||||
request.onerror=function(){reject(new Error("Network Error"));};request.send(params);})};return{'get':function(path,headers={},params={}){return call('GET',path+((params.length>0)?'?'+buildQuery(params):''),headers,{});},'post':function(path,headers={},params={},progress=null){return call('POST',path,headers,params,progress);},'put':function(path,headers={},params={},progress=null){return call('PUT',headers,params,progress);},'patch':function(path,headers={},params={},progress=null){return call('PATCH',path,headers,params,progress);},'delete':function(path,headers={},params={},progress=null){return call('DELETE',path,headers,params,progress);},'addGlobalParam':addGlobalParam,'addGlobalHeader':addGlobalHeader}}(window.document);let analytics={create:function(id,source,activity,url){return http.post('/analytics',{'content-type':'application/json'},{id:id,source:source,activity:activity,url:url,version:env.VERSION,setup:env.SETUP});},};return{analytics:analytics,};},true);})(window);(function(window){"use strict";window.ls.container.set('console',function(window){var client=new Appwrite.Client();var endpoint=window.location.origin+'/v1';client.setEndpoint(endpoint).setProject('console').setLocale(APP_ENV.LOCALE);return{client:client,account:new Appwrite.Account(client),avatars:new Appwrite.Avatars(client),databases:new Appwrite.Databases(client),functions:new Appwrite.Functions(client),health:new Appwrite.Health(client),locale:new Appwrite.Locale(client),projects:new Appwrite.Projects(client),storage:new Appwrite.Storage(client),teams:new Appwrite.Teams(client),users:new Appwrite.Users(client)}},true);})(window);(function(window){"use strict";window.ls.container.set('date',function(){function format(format,datetime){if(!datetime){return null;}
|
||||
return new Intl.DateTimeFormat('en-US',{timeZone:'UTC',hourCycle:'h24',...format}).format(new Date(datetime));}
|
||||
return new Intl.DateTimeFormat(navigator.languages,{hourCycle:'h24',...format}).format(new Date(datetime));}
|
||||
return{format:format,}}(),true);})(window);(function(window){"use strict";window.ls.container.set('env',function(){return APP_ENV;},true);})(window);(function(window){"use strict";window.ls.container.set('form',function(){function cast(value,from,to,){if(value&&Array.isArray(value)&&to!=='array'){value=value.map(element=>cast(element,from,to));return value;}
|
||||
switch(to){case'int':case'integer':value=parseInt(value);break;case'numeric':value=Number(value);break;case'float':value=parseFloat(value);break;case'string':value=value.toString();if(value.length===0){value=null;}
|
||||
break;case'json':value=(value)?JSON.parse(value):[];break;case'array':if(value&&value.constructor&&value.constructor===Array){break;}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
(function (exports, isomorphicFormData, crossFetch) {
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
/******************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
function __awaiter(thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
}
|
||||
|
||||
class Service {
|
||||
|
|
@ -93,7 +93,10 @@
|
|||
mode: '',
|
||||
};
|
||||
this.headers = {
|
||||
'x-sdk-version': 'appwrite:web:6.0.0',
|
||||
'x-sdk-name': 'Console',
|
||||
'x-sdk-platform': 'console',
|
||||
'x-sdk-language': 'web',
|
||||
'x-sdk-version': '6.0.0',
|
||||
'X-Appwrite-Response-Format': '0.15.0',
|
||||
};
|
||||
this.realtime = {
|
||||
|
|
@ -563,20 +566,16 @@
|
|||
* Get currently logged in user list of latest security activity logs. Each
|
||||
* log returns user IP address, location and date and time of log.
|
||||
*
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getLogs(limit, offset) {
|
||||
getLogs(queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/account/logs';
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
|
|
@ -1649,37 +1648,21 @@
|
|||
* Get a list of all databases from the current Appwrite project. You can use
|
||||
* the search parameter to filter your results.
|
||||
*
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
list(search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
list(queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/databases';
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -1822,40 +1805,24 @@
|
|||
* can use the search parameter to filter your results.
|
||||
*
|
||||
* @param {string} databaseId
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listCollections(databaseId, search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
listCollections(databaseId, queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof databaseId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "databaseId"');
|
||||
}
|
||||
let path = '/databases/{databaseId}/collections'.replace('{databaseId}', databaseId);
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -2580,16 +2547,10 @@
|
|||
* @param {string} databaseId
|
||||
* @param {string} collectionId
|
||||
* @param {string[]} queries
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string[]} orderAttributes
|
||||
* @param {string[]} orderTypes
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listDocuments(databaseId, collectionId, queries, limit, offset, cursor, cursorDirection, orderAttributes, orderTypes) {
|
||||
listDocuments(databaseId, collectionId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof databaseId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "databaseId"');
|
||||
|
|
@ -2602,24 +2563,6 @@
|
|||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderAttributes !== 'undefined') {
|
||||
payload['orderAttributes'] = orderAttributes;
|
||||
}
|
||||
if (typeof orderTypes !== 'undefined') {
|
||||
payload['orderTypes'] = orderTypes;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -2781,12 +2724,11 @@
|
|||
* @param {string} databaseId
|
||||
* @param {string} collectionId
|
||||
* @param {string} documentId
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listDocumentLogs(databaseId, collectionId, documentId, limit, offset) {
|
||||
listDocumentLogs(databaseId, collectionId, documentId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof databaseId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "databaseId"');
|
||||
|
|
@ -2799,11 +2741,8 @@
|
|||
}
|
||||
let path = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/logs'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId).replace('{documentId}', documentId);
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
|
|
@ -2951,12 +2890,11 @@
|
|||
*
|
||||
* @param {string} databaseId
|
||||
* @param {string} collectionId
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listCollectionLogs(databaseId, collectionId, limit, offset) {
|
||||
listCollectionLogs(databaseId, collectionId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof databaseId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "databaseId"');
|
||||
|
|
@ -2966,11 +2904,8 @@
|
|||
}
|
||||
let path = '/databases/{databaseId}/collections/{collectionId}/logs'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId);
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
|
|
@ -3008,28 +2943,24 @@
|
|||
});
|
||||
}
|
||||
/**
|
||||
* List Collection Logs
|
||||
* List Database Logs
|
||||
*
|
||||
* Get the collection activity logs list by its unique ID.
|
||||
* Get the database activity logs list by its unique ID.
|
||||
*
|
||||
* @param {string} databaseId
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listLogs(databaseId, limit, offset) {
|
||||
listLogs(databaseId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof databaseId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "databaseId"');
|
||||
}
|
||||
let path = '/databases/{databaseId}/logs'.replace('{databaseId}', databaseId);
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
|
|
@ -3074,37 +3005,21 @@
|
|||
* Get a list of all the project's functions. You can use the query params to
|
||||
* filter your results.
|
||||
*
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
list(search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
list(queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/functions';
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -3309,40 +3224,24 @@
|
|||
* params to filter your results.
|
||||
*
|
||||
* @param {string} functionId
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listDeployments(functionId, search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
listDeployments(functionId, queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof functionId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "functionId"');
|
||||
}
|
||||
let path = '/functions/{functionId}/deployments'.replace('{functionId}', functionId);
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -3556,36 +3455,24 @@
|
|||
* different API modes](/docs/admin).
|
||||
*
|
||||
* @param {string} functionId
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listExecutions(functionId, limit, offset, search, cursor, cursorDirection) {
|
||||
listExecutions(functionId, queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof functionId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "functionId"');
|
||||
}
|
||||
let path = '/functions/{functionId}/executions'.replace('{functionId}', functionId);
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -5217,37 +5104,21 @@
|
|||
* Get a list of all the storage buckets. You can use the query params to
|
||||
* filter your results.
|
||||
*
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listBuckets(search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
listBuckets(queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/storage/buckets';
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -5266,12 +5137,13 @@
|
|||
* @param {boolean} enabled
|
||||
* @param {number} maximumFileSize
|
||||
* @param {string[]} allowedFileExtensions
|
||||
* @param {string} compression
|
||||
* @param {boolean} encryption
|
||||
* @param {boolean} antivirus
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
createBucket(bucketId, name, fileSecurity, permissions, enabled, maximumFileSize, allowedFileExtensions, encryption, antivirus) {
|
||||
createBucket(bucketId, name, fileSecurity, permissions, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof bucketId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "bucketId"');
|
||||
|
|
@ -5305,6 +5177,9 @@
|
|||
if (typeof allowedFileExtensions !== 'undefined') {
|
||||
payload['allowedFileExtensions'] = allowedFileExtensions;
|
||||
}
|
||||
if (typeof compression !== 'undefined') {
|
||||
payload['compression'] = compression;
|
||||
}
|
||||
if (typeof encryption !== 'undefined') {
|
||||
payload['encryption'] = encryption;
|
||||
}
|
||||
|
|
@ -5352,12 +5227,13 @@
|
|||
* @param {boolean} enabled
|
||||
* @param {number} maximumFileSize
|
||||
* @param {string[]} allowedFileExtensions
|
||||
* @param {string} compression
|
||||
* @param {boolean} encryption
|
||||
* @param {boolean} antivirus
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
updateBucket(bucketId, name, fileSecurity, permissions, enabled, maximumFileSize, allowedFileExtensions, encryption, antivirus) {
|
||||
updateBucket(bucketId, name, fileSecurity, permissions, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof bucketId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "bucketId"');
|
||||
|
|
@ -5388,6 +5264,9 @@
|
|||
if (typeof allowedFileExtensions !== 'undefined') {
|
||||
payload['allowedFileExtensions'] = allowedFileExtensions;
|
||||
}
|
||||
if (typeof compression !== 'undefined') {
|
||||
payload['compression'] = compression;
|
||||
}
|
||||
if (typeof encryption !== 'undefined') {
|
||||
payload['encryption'] = encryption;
|
||||
}
|
||||
|
|
@ -5430,40 +5309,24 @@
|
|||
* project's files. [Learn more about different API modes](/docs/admin).
|
||||
*
|
||||
* @param {string} bucketId
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listFiles(bucketId, search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
listFiles(bucketId, queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof bucketId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "bucketId"');
|
||||
}
|
||||
let path = '/storage/buckets/{bucketId}/files'.replace('{bucketId}', bucketId);
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -5848,37 +5711,21 @@
|
|||
* In admin mode, this endpoint returns a list of all the teams in the current
|
||||
* project. [Learn more about different API modes](/docs/admin).
|
||||
*
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
list(search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
list(queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/teams';
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -6004,23 +5851,19 @@
|
|||
* Get the team activity logs list by its unique ID.
|
||||
*
|
||||
* @param {string} teamId
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
listLogs(teamId, limit, offset) {
|
||||
listLogs(teamId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof teamId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "teamId"');
|
||||
}
|
||||
let path = '/teams/{teamId}/logs'.replace('{teamId}', teamId);
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
|
|
@ -6035,40 +5878,24 @@
|
|||
* members have read access to this endpoint.
|
||||
*
|
||||
* @param {string} teamId
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getMemberships(teamId, search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
getMemberships(teamId, queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof teamId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "teamId"');
|
||||
}
|
||||
let path = '/teams/{teamId}/memberships'.replace('{teamId}', teamId);
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -6284,37 +6111,21 @@
|
|||
* Get a list of all the project's users. You can use the query params to
|
||||
* filter your results.
|
||||
*
|
||||
* @param {string} queries
|
||||
* @param {string} search
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} cursor
|
||||
* @param {string} cursorDirection
|
||||
* @param {string} orderType
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
list(search, limit, offset, cursor, cursorDirection, orderType) {
|
||||
list(queries, search) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let path = '/users';
|
||||
let payload = {};
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
if (typeof search !== 'undefined') {
|
||||
payload['search'] = search;
|
||||
}
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
}
|
||||
if (typeof cursor !== 'undefined') {
|
||||
payload['cursor'] = cursor;
|
||||
}
|
||||
if (typeof cursorDirection !== 'undefined') {
|
||||
payload['cursorDirection'] = cursorDirection;
|
||||
}
|
||||
if (typeof orderType !== 'undefined') {
|
||||
payload['orderType'] = orderType;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
'content-type': 'application/json',
|
||||
|
|
@ -6852,23 +6663,19 @@
|
|||
* Get the user activity logs list by its unique ID.
|
||||
*
|
||||
* @param {string} userId
|
||||
* @param {number} limit
|
||||
* @param {number} offset
|
||||
* @param {string} queries
|
||||
* @throws {AppwriteException}
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getLogs(userId, limit, offset) {
|
||||
getLogs(userId, queries) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (typeof userId === 'undefined') {
|
||||
throw new AppwriteException('Missing required parameter: "userId"');
|
||||
}
|
||||
let path = '/users/{userId}/logs'.replace('{userId}', userId);
|
||||
let payload = {};
|
||||
if (typeof limit !== 'undefined') {
|
||||
payload['limit'] = limit;
|
||||
}
|
||||
if (typeof offset !== 'undefined') {
|
||||
payload['offset'] = offset;
|
||||
if (typeof queries !== 'undefined') {
|
||||
payload['queries'] = queries;
|
||||
}
|
||||
const uri = new URL(this.client.config.endpoint + path);
|
||||
return yield this.client.call('get', uri, {
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ class Bucket extends Model
|
|||
'example' => ['jpg', 'png'],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('compression', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Compression algorithm choosen for compression. Will be one of ' . COMPRESSION_TYPE_NONE . ', [' . COMPRESSION_TYPE_GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . COMPRESSION_TYPE_ZSTD . '](https://en.wikipedia.org/wiki/Zstd).',
|
||||
'default' => [],
|
||||
'example' => 'gzip',
|
||||
'array' => false
|
||||
])
|
||||
->addRule('encryption', [
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Bucket is encrypted.',
|
||||
|
|
|
|||
|
|
@ -243,6 +243,55 @@ trait StorageBase
|
|||
return ['bucketId' => $bucketId, 'fileId' => $file['body']['$id'], 'largeFileId' => $largeFile['body']['$id'], 'largeBucketId' => $bucket2['body']['$id']];
|
||||
}
|
||||
|
||||
public function testCreateBucketFileZstdCompression(): array
|
||||
{
|
||||
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'bucketId' => ID::unique(),
|
||||
'name' => 'Test Bucket',
|
||||
'fileSecurity' => true,
|
||||
'maximumFileSize' => 2000000, //2MB
|
||||
'allowedFileExtensions' => ["jpg", "png"],
|
||||
'compression' => 'zstd',
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::create(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(201, $bucket['headers']['status-code']);
|
||||
$this->assertNotEmpty($bucket['body']['$id']);
|
||||
$this->assertEquals('zstd', $bucket['body']['compression']);
|
||||
|
||||
$bucketId = $bucket['body']['$id'];
|
||||
|
||||
$file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'fileId' => ID::unique(),
|
||||
'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'),
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(201, $file['headers']['status-code']);
|
||||
$this->assertNotEmpty($file['body']['$id']);
|
||||
$this->assertEquals(true, DateTime::isValid($file['body']['$createdAt']));
|
||||
$this->assertEquals('logo.png', $file['body']['name']);
|
||||
$this->assertEquals('image/png', $file['body']['mimeType']);
|
||||
$this->assertEquals(47218, $file['body']['sizeOriginal']);
|
||||
$this->assertTrue(md5_file(realpath(__DIR__ . '/../../../resources/logo.png')) != $file['body']['signature']); // should validate that the file is encrypted
|
||||
|
||||
return ['bucketId' => $bucketId];
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateBucketFile
|
||||
*/
|
||||
|
|
@ -598,6 +647,50 @@ trait StorageBase
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateBucketFileZstdCompression
|
||||
*/
|
||||
public function testFilePreviewZstdCompression(array $data): array
|
||||
{
|
||||
$bucketId = $data['bucketId'];
|
||||
|
||||
$file = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'fileId' => ID::unique(),
|
||||
'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/logo.png'), 'image/png', 'logo.png'),
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::any()),
|
||||
Permission::delete(Role::any()),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(201, $file['headers']['status-code']);
|
||||
$this->assertNotEmpty($file['body']['$id']);
|
||||
|
||||
$fileId = $file['body']['$id'];
|
||||
|
||||
//get image preview
|
||||
$file3 = $this->client->call(Client::METHOD_GET, '/storage/buckets/' . $bucketId . '/files/' . $fileId . '/preview', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'width' => 300,
|
||||
'height' => 100,
|
||||
'borderRadius' => '50',
|
||||
'opacity' => '0.5',
|
||||
'output' => 'png',
|
||||
'rotation' => '45',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $file3['headers']['status-code']);
|
||||
$this->assertEquals('image/png', $file3['headers']['content-type']);
|
||||
$this->assertNotEmpty($file3['body']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateBucketFile
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue