1
0
Fork 0
mirror of synced 2024-06-02 10:54:44 +12:00

Merge branch 'master' of https://github.com/appwrite/appwrite into fix-bucket-permissions

This commit is contained in:
Torsten Dittmann 2022-03-15 10:52:11 +01:00
commit 0e5dd2def6
27 changed files with 200 additions and 61 deletions

View file

@ -37,6 +37,7 @@ body:
label: "🎲 Appwrite version"
description: "What version of Appwrite are you running?"
options:
- Version 0.13.x
- Version 0.12.x
- Version 0.11.x
- Version 0.10.x

13
.gitpod.Dockerfile vendored Normal file
View file

@ -0,0 +1,13 @@
FROM gitpod/workspace-full
# Disable current PHP installation
RUN sudo a2dismod php7.4
RUN sudo a2dismod mpm_prefork
# Install apache2 (PHP install requires to do this first)
RUN sudo apt --yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install apache2
# Update to PHP 8.0 with unattended installation
RUN sudo apt --yes install software-properties-common && sudo add-apt-repository ppa:ondrej/php -y
RUN sudo apt update
RUN sudo apt --yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install php8.0

24
.gitpod.yml Normal file
View file

@ -0,0 +1,24 @@
image:
file: .gitpod.Dockerfile
tasks:
- init: docker-compose pull &&
docker-compose build &&
docker run --rm --interactive --tty --volume $PWD:/app composer update --ignore-platform-reqs --optimize-autoloader --no-plugins --no-scripts --prefer-dist
ports:
- port: 8080
onOpen: open-preview
visibility: public
vscode:
extensions:
- ms-azuretools.vscode-docker
github:
# https://www.gitpod.io/docs/prebuilds#github-specific-configuration
prebuilds:
# enable for pull requests coming from forks (defaults to false)
pullRequestsFromForks: true
# add a check to pull requests (defaults to true)
addCheck: false

View file

@ -1,11 +1,18 @@
# Version 0.13.1 (NOT RELEASED)
# Version 0.13.2
## Bugs
- Fixed global issue with write permissions
- Added missing `_APP_EXECUTOR_SECRET` environment variable for deletes worker
- Increased execution `stdout` and `stderr` from 8000 to 16384 character limit
- Increased maximum file size for image preview to 20mb
- Fixed iOS platforms for origin validation by @stnguyen90 in https://github.com/appwrite/appwrite/pull/2907
# Version 0.13.1
## Bugs
- Fixed the Console UI redirect breaking the header and navigation
- Fixed timeout in Functions API to respect the environment variable `_APP_FUNCTIONS_TIMEOUT`
- Fixed team invite to be invalid after successful use by @Malte2036 in https://github.com/appwrite/appwrite/issues/2593
# Version 0.13.0
## Features
### Functions
- Synchronous function execution

View file

@ -59,7 +59,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:0.13.1
appwrite/appwrite:0.13.2
```
### Windows
@ -71,7 +71,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:0.13.1
appwrite/appwrite:0.13.2
```
#### PowerShell
@ -81,7 +81,7 @@ docker run -it --rm ,
--volume /var/run/docker.sock:/var/run/docker.sock ,
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
--entrypoint="install" ,
appwrite/appwrite:0.13.1
appwrite/appwrite:0.13.2
```
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。

View file

@ -53,7 +53,7 @@ Table of Contents:
Appwrite backend server is designed to run in a container environment. Running your server is as easy as running one command from your terminal. You can either run Appwrite on your localhost using docker-compose or on any other container orchestration tool like Kubernetes, Docker Swarm, or Rancher.
The easiest way to start running your Appwrite server is by running our docker-compose file. Before running the installation command make sure you have [Docker](https://www.docker.com/products/docker-desktop) installed on your machine:
The easiest way to start running your Appwrite server is by running our docker-compose file. Before running the installation command, make sure you have [Docker](https://www.docker.com/products/docker-desktop) installed on your machine:
### Unix
@ -62,7 +62,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:0.13.1
appwrite/appwrite:0.13.2
```
### Windows
@ -74,7 +74,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:0.13.1
appwrite/appwrite:0.13.2
```
#### PowerShell
@ -84,7 +84,7 @@ docker run -it --rm ,
--volume /var/run/docker.sock:/var/run/docker.sock ,
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
--entrypoint="install" ,
appwrite/appwrite:0.13.1
appwrite/appwrite:0.13.2
```
Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after installation completes.

View file

@ -4,6 +4,7 @@ use Appwrite\Auth\Auth;
use Appwrite\Auth\Validator\Password;
use Appwrite\Network\Validator\CNAME;
use Appwrite\Network\Validator\Domain as DomainValidator;
use Appwrite\Network\Validator\Origin;
use Appwrite\Network\Validator\URL;
use Appwrite\Utopia\Database\Validator\CustomId;
use Appwrite\Utopia\Response;
@ -1002,7 +1003,7 @@ App::post('/v1/projects/:projectId/platforms')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PLATFORM)
->param('projectId', null, new UID(), 'Project unique ID.')
->param('type', null, new WhiteList(['web', 'flutter-ios', 'flutter-android', 'flutter-linux', 'flutter-macos', 'flutter-windows', 'apple-ios', 'apple-macos', 'apple-watchos', 'apple-tvos', 'android', 'unity'], true), 'Platform type.')
->param('type', null, new WhiteList([Origin::CLIENT_TYPE_WEB, Origin::CLIENT_TYPE_FLUTTER_IOS, Origin::CLIENT_TYPE_FLUTTER_ANDROID, Origin::CLIENT_TYPE_FLUTTER_LINUX, Origin::CLIENT_TYPE_FLUTTER_MACOS, Origin::CLIENT_TYPE_FLUTTER_WINDOWS, Origin::CLIENT_TYPE_APPLE_IOS, Origin::CLIENT_TYPE_APPLE_MACOS, Origin::CLIENT_TYPE_APPLE_WATCHOS, Origin::CLIENT_TYPE_APPLE_TVOS, Origin::CLIENT_TYPE_ANDROID, Origin::CLIENT_TYPE_UNITY], true), 'Platform type.')
->param('name', null, new Text(128), 'Platform name. Max length: 128 chars.')
->param('key', '', new Text(256), 'Package name for Android or bundle ID for iOS or macOS. Max length: 256 chars.', true)
->param('store', '', new Text(256), 'App store or Google Play store ID. Max length: 256 chars.', true)

View file

@ -1346,7 +1346,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
/** @var Utopia\Database\Document $user */
/** @var Appwrite\Event\Event $audits */
/** @var Appwrite\Stats\Stats $usage */
/** @var Appwirte\Event\Event $events */
/** @var Appwrite\Event\Event $events */
/** @var string $mode */
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));

View file

@ -500,8 +500,8 @@ App::post('/v1/execution')
$execution = [
'status' => $functionStatus,
'statusCode' => $statusCode,
'stdout' => \utf8_encode(\mb_substr($stdout, -8000)),
'stderr' => \utf8_encode(\mb_substr($stderr, -8000)),
'stdout' => \utf8_encode(\mb_substr($stdout, -16384)),
'stderr' => \utf8_encode(\mb_substr($stderr, -16384)),
'time' => $executionTime,
];

View file

@ -69,9 +69,9 @@ const APP_LIMIT_USERS = 10000;
const APP_LIMIT_ANTIVIRUS = 20000000; //20MB
const APP_LIMIT_ENCRYPTION = 20000000; //20MB
const APP_LIMIT_COMPRESSION = 20000000; //20MB
const APP_LIMIT_PREVIEW = 10000000; //10MB file size limit for preview endpoint
const APP_CACHE_BUSTER = 301;
const APP_VERSION_STABLE = '0.13.1';
const APP_LIMIT_PREVIEW = 20000000; //20MB file size limit for preview endpoint
const APP_CACHE_BUSTER = 302;
const APP_VERSION_STABLE = '0.13.2';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';

View file

@ -762,21 +762,21 @@ $logs = $this->getParam('logs', null);
<div class="row responsive thin">
<div class="col span-6 margin-bottom-small">
<label for="float-min">Min</label>
<input id="float-min" type="number" class="full-width" name="min" step="0.01" autocomplete="off" data-cast-to="float" />
<input id="float-min" type="number" class="full-width" name="min" step="any" autocomplete="off" data-cast-to="float" />
</div>
<div class="col span-6 margin-bottom-small">
<label for="float-max">Max</label>
<input id="float-max" type="number" class="full-width" name="max" step="0.01" autocomplete="off" data-cast-to="float" />
<input id="float-max" type="number" class="full-width" name="max" step="any" autocomplete="off" data-cast-to="float" />
</div>
</div>
<label for="float-default">Default Value</label>
<template x-if="!(array || required)">
<input name="xdefault" type="number" step="0.01" class="margin-bottom-large" autocomplete="off" data-cast-to="float">
<input name="xdefault" type="number" step="any" class="margin-bottom-large" autocomplete="off" data-cast-to="float">
</template>
<template x-if="(array || required)">
<input name="xdefault" type="number" step="0.01" class="margin-bottom-large" autocomplete="off" data-cast-to="float" disabled>
<input name="xdefault" type="number" step="any" class="margin-bottom-large" autocomplete="off" data-cast-to="float" disabled>
</template>
<footer>

View file

@ -110,7 +110,7 @@ $logs = $this->getParam('logs', null);
<template x-if="attr.type === 'double'">
<input
type="number"
step="0.01"
step="any"
:placeholder="attr.default"
:name="attr.key"
:required="attr.required"
@ -203,7 +203,7 @@ $logs = $this->getParam('logs', null);
<template x-if="attr.type === 'double'">
<input
type="number"
step="0.01"
step="any"
:placeholder="attr.default"
:name="attr.key"
:required="attr.required"

View file

@ -173,6 +173,7 @@ services:
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
entrypoint: executor
container_name: appwrite-executor
restart: unless-stopped
stop_signal: SIGINT
networks:
appwrite:
@ -344,6 +345,7 @@ services:
- _APP_STORAGE_DO_SPACES_BUCKET
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_EXECUTOR_SECRET
appwrite-worker-certificates:
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
@ -560,4 +562,4 @@ volumes:
appwrite-functions:
appwrite-influxdb:
appwrite-config:
appwrite-executor:
appwrite-executor:

64
composer.lock generated
View file

@ -1646,7 +1646,7 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@ -1708,7 +1708,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
},
"funding": [
{
@ -1728,16 +1728,16 @@
},
{
"name": "symfony/polyfill-php80",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
"shasum": ""
},
"require": {
@ -1791,7 +1791,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
},
"funding": [
{
@ -1807,7 +1807,7 @@
"type": "tidelift"
}
],
"time": "2021-09-13T13:58:33+00:00"
"time": "2022-03-04T08:16:47+00:00"
},
{
"name": "utopia-php/abuse",
@ -2129,16 +2129,16 @@
},
{
"name": "utopia-php/database",
"version": "0.15.2",
"version": "0.15.3",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "4ae9f1162d6640ccfe28afa0bbc60b907a7ad1c0"
"reference": "726e3b04fb1f1b3b654bc1d3114deaf1481cb008"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/4ae9f1162d6640ccfe28afa0bbc60b907a7ad1c0",
"reference": "4ae9f1162d6640ccfe28afa0bbc60b907a7ad1c0",
"url": "https://api.github.com/repos/utopia-php/database/zipball/726e3b04fb1f1b3b654bc1d3114deaf1481cb008",
"reference": "726e3b04fb1f1b3b654bc1d3114deaf1481cb008",
"shasum": ""
},
"require": {
@ -2186,9 +2186,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.15.2"
"source": "https://github.com/utopia-php/database/tree/0.15.3"
},
"time": "2022-02-28T15:53:37+00:00"
"time": "2022-03-07T11:59:51+00:00"
},
{
"name": "utopia-php/domains",
@ -3677,16 +3677,16 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.10.3",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "c6a951b75d684fd43fbbd69617488e1e2e8924ba"
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/c6a951b75d684fd43fbbd69617488e1e2e8924ba",
"reference": "c6a951b75d684fd43fbbd69617488e1e2e8924ba",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
"shasum": ""
},
"require": {
@ -3724,7 +3724,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.10.3"
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
},
"funding": [
{
@ -3732,7 +3732,7 @@
"type": "tidelift"
}
],
"time": "2022-03-02T14:16:47+00:00"
"time": "2022-03-03T13:19:32+00:00"
},
{
"name": "netresearch/jsonmapper",
@ -4234,16 +4234,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.14",
"version": "9.2.15",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4"
"reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f4d60b6afe5546421462b76cd4e633ebc364ab4",
"reference": "9f4d60b6afe5546421462b76cd4e633ebc364ab4",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f",
"reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f",
"shasum": ""
},
"require": {
@ -4299,7 +4299,7 @@
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.14"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15"
},
"funding": [
{
@ -4307,7 +4307,7 @@
"type": "github"
}
],
"time": "2022-02-28T12:38:02+00:00"
"time": "2022-03-07T09:28:20+00:00"
},
{
"name": "phpunit/php-file-iterator",
@ -5809,7 +5809,7 @@
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
@ -5870,7 +5870,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0"
},
"funding": [
{
@ -5890,7 +5890,7 @@
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
@ -5954,7 +5954,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0"
},
"funding": [
{
@ -5974,7 +5974,7 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@ -6037,7 +6037,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
},
"funding": [
{

View file

@ -22,6 +22,7 @@ services:
- --accesslog=true
ports:
- 80:80
- 8080:80
- 443:443
- 9500:8080
volumes:
@ -280,6 +281,7 @@ services:
- _APP_STORAGE_DO_SPACES_BUCKET
- _APP_LOGGING_PROVIDER
- _APP_LOGGING_CONFIG
- _APP_EXECUTOR_SECRET
appwrite-worker-database:
entrypoint: worker-database

View file

@ -3741,7 +3741,7 @@ window.ls.container.get("view").add({selector:"data-acl",controller:function(ele
if("/console"===router.getCurrent().path){document.body.classList.add("index");}else{document.body.classList.remove("index");}}}).add({selector:"data-prism",controller:function(window,document,element,alerts){Prism.highlightElement(element);let copy=document.createElement("i");copy.className="icon-docs copy";copy.title="Copy to Clipboard";copy.textContent="Click Here to Copy";copy.addEventListener("click",function(){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand("copy");alerts.add({text:"Copied to clipboard",class:""},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:"error"},3000);}
window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}});(function(window){document.addEventListener('alpine:init',()=>{Alpine.store('uploader',{_files:[],files(){return(this._files??[]).filter((file)=>!file.cancelled);},isOpen:true,init(){window.addEventListener('beforeunload',(event)=>{if(this.hasOngoingUploads()){let confirmationMessage="There are incomplete uploads, are you sure you want to leave?";event.returnValue=confirmationMessage;return confirmationMessage;}});},cancelAll(){if(this.hasOngoingUploads()?confirm("Are you sure? This will cancel and remove any ongoing uploads?"):true){this._files.forEach(file=>{if(file.completed||file.failed){this.removeFile(file.id);}else{this.updateFile(file.id,{cancelled:true});}});}},hasOngoingUploads(){let ongoing=false;this._files.some((file)=>{if(!file.completed&&!file.failed){ongoing=true;return;}});return ongoing;},toggle(){this.isOpen=!this.isOpen;},addFile(file){this._files.push(file);},updateFile(id,file){this._files=this._files.map((oldFile)=>id==oldFile.id?{...oldFile,...file}:oldFile);},removeFile(id){const file=this.getFile(id)??{};if(file.completed||file.failed){this._files=this._files.filter((file)=>file.id!==id);}else{if(confirm("Are you sure you want to cancel the upload?")){this.updateFile(id,{cancelled:true});}}},getFile(id){return this._files.find((file)=>file.id===id);},async uploadFile(target){const formData=new FormData(target);const sdk=window.ls.container.get('sdk');const bucketId=formData.get('bucketId');const file=formData.get('file');const fileId=formData.get('fileId');let id=fileId==='unique()'?performance.now():fileId;let read=formData.get('read');if(!file||!fileId){return;}
if(read){read=JSON.parse(read);}
let write=formData.get('write');if(write){write=JSON.parse(wirte);}
let write=formData.get('write');if(write){write=JSON.parse(write);}
if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:false,cancelled:false,error:"",});}else{this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,cancelled:false,error:"",});}
target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;}
document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});}

View file

@ -691,7 +691,7 @@ window.ls.container.get("view").add({selector:"data-acl",controller:function(ele
if("/console"===router.getCurrent().path){document.body.classList.add("index");}else{document.body.classList.remove("index");}}}).add({selector:"data-prism",controller:function(window,document,element,alerts){Prism.highlightElement(element);let copy=document.createElement("i");copy.className="icon-docs copy";copy.title="Copy to Clipboard";copy.textContent="Click Here to Copy";copy.addEventListener("click",function(){window.getSelection().removeAllRanges();let range=document.createRange();range.selectNode(element);window.getSelection().addRange(range);try{document.execCommand("copy");alerts.add({text:"Copied to clipboard",class:""},3000);}catch(err){alerts.add({text:"Failed to copy text ",class:"error"},3000);}
window.getSelection().removeAllRanges();});element.parentNode.parentNode.appendChild(copy);}});(function(window){document.addEventListener('alpine:init',()=>{Alpine.store('uploader',{_files:[],files(){return(this._files??[]).filter((file)=>!file.cancelled);},isOpen:true,init(){window.addEventListener('beforeunload',(event)=>{if(this.hasOngoingUploads()){let confirmationMessage="There are incomplete uploads, are you sure you want to leave?";event.returnValue=confirmationMessage;return confirmationMessage;}});},cancelAll(){if(this.hasOngoingUploads()?confirm("Are you sure? This will cancel and remove any ongoing uploads?"):true){this._files.forEach(file=>{if(file.completed||file.failed){this.removeFile(file.id);}else{this.updateFile(file.id,{cancelled:true});}});}},hasOngoingUploads(){let ongoing=false;this._files.some((file)=>{if(!file.completed&&!file.failed){ongoing=true;return;}});return ongoing;},toggle(){this.isOpen=!this.isOpen;},addFile(file){this._files.push(file);},updateFile(id,file){this._files=this._files.map((oldFile)=>id==oldFile.id?{...oldFile,...file}:oldFile);},removeFile(id){const file=this.getFile(id)??{};if(file.completed||file.failed){this._files=this._files.filter((file)=>file.id!==id);}else{if(confirm("Are you sure you want to cancel the upload?")){this.updateFile(id,{cancelled:true});}}},getFile(id){return this._files.find((file)=>file.id===id);},async uploadFile(target){const formData=new FormData(target);const sdk=window.ls.container.get('sdk');const bucketId=formData.get('bucketId');const file=formData.get('file');const fileId=formData.get('fileId');let id=fileId==='unique()'?performance.now():fileId;let read=formData.get('read');if(!file||!fileId){return;}
if(read){read=JSON.parse(read);}
let write=formData.get('write');if(write){write=JSON.parse(wirte);}
let write=formData.get('write');if(write){write=JSON.parse(write);}
if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:false,cancelled:false,error:"",});}else{this.addFile({id:id,name:file.name,progress:0,completed:false,failed:false,cancelled:false,error:"",});}
target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;}
document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});}

View file

@ -74,7 +74,7 @@
}
let write = formData.get('write');
if(write) {
write = JSON.parse(wirte);
write = JSON.parse(write);
}
if(this.getFile(id)) {
@ -159,4 +159,4 @@
});
});
})(window);
})(window);

View file

@ -37,6 +37,7 @@ abstract class Migration
public static array $versions = [
'0.13.0' => 'V12',
'0.13.1' => 'V12',
'0.13.2' => 'V12',
];
/**

View file

@ -13,8 +13,12 @@ class Origin extends Validator
public const CLIENT_TYPE_FLUTTER_MACOS = 'flutter-macos';
public const CLIENT_TYPE_FLUTTER_WINDOWS = 'flutter-windows';
public const CLIENT_TYPE_FLUTTER_LINUX = 'flutter-linux';
public const CLIENT_TYPE_APPLE_IOS = 'apple-ios';
public const CLIENT_TYPE_APPLE_MACOS = 'apple-macos';
public const CLIENT_TYPE_APPLE_WATCHOS = 'apple-watchos';
public const CLIENT_TYPE_APPLE_TVOS = 'apple-tvos';
public const CLIENT_TYPE_ANDROID = 'android';
public const CLIENT_TYPE_IOS = 'ios';
public const CLIENT_TYPE_UNITY = 'unity';
public const SCHEME_TYPE_HTTP = 'http';
@ -73,7 +77,7 @@ class Origin extends Validator
case self::CLIENT_TYPE_FLUTTER_WINDOWS:
case self::CLIENT_TYPE_FLUTTER_LINUX:
case self::CLIENT_TYPE_ANDROID:
case self::CLIENT_TYPE_IOS:
case self::CLIENT_TYPE_APPLE_IOS:
$this->clients[] = (isset($platform['key'])) ? $platform['key'] : '';
break;

View file

@ -12,6 +12,18 @@ class AttributeBoolean extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'isEnabled',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'boolean',
])
->addRule('default', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',

View file

@ -12,6 +12,18 @@ class AttributeEmail extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'userEmail',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'string',
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',

View file

@ -12,6 +12,18 @@ class AttributeEnum extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'status',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'string',
])
->addRule('elements', [
'type' => self::TYPE_STRING,
'description' => 'Array of elements in enumerated type.',

View file

@ -12,6 +12,18 @@ class AttributeFloat extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'percentageCompleted',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'double',
])
->addRule('min', [
'type' => self::TYPE_FLOAT,
'description' => 'Minimum value to enforce for new documents.',

View file

@ -12,6 +12,18 @@ class AttributeIP extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'ipAddress',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'string',
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',

View file

@ -12,6 +12,18 @@ class AttributeInteger extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'count',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'integer',
])
->addRule('min', [
'type' => self::TYPE_INTEGER,
'description' => 'Minimum value to enforce for new documents.',

View file

@ -12,6 +12,18 @@ class AttributeURL extends Attribute
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'githubUrl',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Attribute type.',
'default' => '',
'example' => 'string',
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',