diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000000..ec2953a161 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,11 @@ +reviews: + path_filters: + - "!app/config/specs/**" + - "!docs/examples/**" + - "!docs/references/**" + - "!docs/sdks/**" + auto_review: + base_branches: + - main + - 1.6.x + - 1.7.x \ No newline at end of file diff --git a/.env b/.env index 89b76cb740..4980315c9a 100644 --- a/.env +++ b/.env @@ -19,11 +19,14 @@ _APP_CUSTOM_DOMAIN_DENY_LIST= _APP_OPTIONS_ABUSE=disabled _APP_OPTIONS_ROUTER_PROTECTION=disabled _APP_OPTIONS_FORCE_HTTPS=disabled -_APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled +_APP_OPTIONS_ROUTER_FORCE_HTTPS=disabled _APP_OPENSSL_KEY_V1=your-secret-key _APP_DOMAIN=traefik _APP_DOMAIN_FUNCTIONS=functions.localhost -_APP_DOMAIN_TARGET=localhost +_APP_DOMAIN_SITES=sites.localhost +_APP_DOMAIN_TARGET_CNAME=test.appwrite.io +_APP_DOMAIN_TARGET_A=127.0.0.1 +_APP_DOMAIN_TARGET_AAAA=::1 _APP_RULES_FORMAT=md5 _APP_REDIS_HOST=redis _APP_REDIS_PORT=6379 @@ -70,17 +73,19 @@ _APP_SMS_FROM=+123456789 _APP_SMS_PROJECTS_DENY_LIST= _APP_STORAGE_LIMIT=30000000 _APP_STORAGE_PREVIEW_LIMIT=20000000 -_APP_FUNCTIONS_SIZE_LIMIT=30000000 +_APP_COMPUTE_SIZE_LIMIT=30000000 _APP_FUNCTIONS_TIMEOUT=900 -_APP_FUNCTIONS_BUILD_TIMEOUT=900 -_APP_FUNCTIONS_CPUS=8 -_APP_FUNCTIONS_MEMORY=8192 -_APP_FUNCTIONS_INACTIVE_THRESHOLD=600 -_APP_FUNCTIONS_MAINTENANCE_INTERVAL=600 -_APP_FUNCTIONS_RUNTIMES_NETWORK=runtimes +_APP_SITES_TIMEOUT=30 +_APP_COMPUTE_BUILD_TIMEOUT=900 +_APP_COMPUTE_CPUS=8 +_APP_COMPUTE_MEMORY=8192 +_APP_COMPUTE_INACTIVE_THRESHOLD=600 +_APP_COMPUTE_MAINTENANCE_INTERVAL=600 +_APP_COMPUTE_RUNTIMES_NETWORK=runtimes _APP_EXECUTOR_SECRET=your-secret-key -_APP_EXECUTOR_HOST=http://proxy/v1 +_APP_EXECUTOR_HOST=http://exc1/v1 _APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1 +_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29 _APP_MAINTENANCE_INTERVAL=86400 _APP_MAINTENANCE_START_TIME=12:00 _APP_MAINTENANCE_RETENTION_CACHE=2592000 @@ -89,7 +94,7 @@ _APP_MAINTENANCE_RETENTION_ABUSE=86400 _APP_MAINTENANCE_RETENTION_AUDIT=1209600 _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE=15778800 _APP_USAGE_AGGREGATION_INTERVAL=30 -_APP_STATS_RESOURCES_INTERVAL=3600 +_APP_STATS_RESOURCES_INTERVAL=30 _APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000 _APP_MAINTENANCE_RETENTION_SCHEDULES=86400 _APP_USAGE_STATS=enabled diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 0000000000..6d73787d00 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,120 @@ +name: Benchmark +concurrency: + group: '${{ github.workflow }}-${{ github.ref }}' + cancel-in-progress: true +env: + IMAGE: appwrite-dev + CACHE_KEY: 'appwrite-dev-${{ github.event.pull_request.head.sha }}' +'on': + - pull_request +jobs: + setup: + name: Setup & Build Appwrite Image + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build Appwrite + uses: docker/build-push-action@v6 + with: + context: . + push: false + tags: '${{ env.IMAGE }}' + load: true + cache-from: type=gha + cache-to: 'type=gha,mode=max' + outputs: 'type=docker,dest=/tmp/${{ env.IMAGE }}.tar' + build-args: | + DEBUG=false + TESTING=true + VERSION=dev + - name: Cache Docker Image + uses: actions/cache@v4 + with: + key: '${{ env.CACHE_KEY }}' + path: '/tmp/${{ env.IMAGE }}.tar' + benchmarking: + name: Benchmark + runs-on: ubuntu-latest + needs: setup + permissions: + pull-requests: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Load Cache + uses: actions/cache@v4 + with: + key: '${{ env.CACHE_KEY }}' + path: '/tmp/${{ env.IMAGE }}.tar' + fail-on-cache-miss: true + - name: Load and Start Appwrite + run: | + sed -i 's/traefik/localhost/g' .env + docker load --input /tmp/${{ env.IMAGE }}.tar + docker compose up -d + sleep 10 + - name: Install Oha + run: | + echo "deb [signed-by=/usr/share/keyrings/azlux-archive-keyring.gpg] http://packages.azlux.fr/debian/ stable main" | sudo tee /etc/apt/sources.list.d/azlux.list + sudo wget -O /usr/share/keyrings/azlux-archive-keyring.gpg https://azlux.fr/repo.gpg + sudo apt update + sudo apt install oha + - name: Benchmark PR + run: 'oha -z 180s http://localhost/v1/health/version -j > benchmark.json' + - name: Cleaning + run: docker compose down -v + - name: Installing latest version + run: | + rm docker-compose.yml + rm .env + curl https://appwrite.io/install/compose -o docker-compose.yml + curl https://appwrite.io/install/env -o .env + sed -i 's/_APP_OPTIONS_ABUSE=enabled/_APP_OPTIONS_ABUSE=disabled/g' .env + docker compose up -d + sleep 10 + - name: Benchmark Latest + run: oha -z 180s http://localhost/v1/health/version -j > benchmark-latest.json + - name: Prepare comment + run: | + echo '## :sparkles: Benchmark results' > benchmark.txt + echo ' ' >> benchmark.txt + echo "- Requests per second: $(jq -r '.summary.requestsPerSec|tonumber?|floor|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json)" >> benchmark.txt + echo "- Requests with 200 status code: $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json)" >> benchmark.txt + echo "- P99 latency: $(jq -r '.latencyPercentiles.p99' benchmark.json )" >> benchmark.txt + echo " " >> benchmark.txt + echo " " >> benchmark.txt + echo "## :zap: Benchmark Comparison" >> benchmark.txt + echo " " >> benchmark.txt + echo "| Metric | This PR | Latest version | " >> benchmark.txt + echo "| --- | --- | --- | " >> benchmark.txt + echo "| RPS | $(jq -r '.summary.requestsPerSec|tonumber?|floor|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json) | $(jq -r '.summary.requestsPerSec|tonumber|floor|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark-latest.json) | " >> benchmark.txt + echo "| 200 | $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json) | $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark-latest.json) | " >> benchmark.txt + echo "| P99 | $(jq -r '.latencyPercentiles.p99' benchmark.json ) | $(jq -r '.latencyPercentiles.p99' benchmark-latest.json ) | " >> benchmark.txt + - name: Save results + uses: actions/upload-artifact@v4 + if: '${{ !cancelled() }}' + with: + name: benchmark.json + path: benchmark.json + retention-days: 7 + - name: Find Comment + if: github.event.pull_request.head.repo.full_name == github.repository + uses: peter-evans/find-comment@v3 + id: fc + with: + issue-number: '${{ github.event.pull_request.number }}' + comment-author: 'github-actions[bot]' + body-includes: Benchmark results + - name: Comment on PR + if: github.event.pull_request.head.repo.full_name == github.repository + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: '${{ steps.fc.outputs.comment-id }}' + issue-number: '${{ github.event.pull_request.number }}' + body-path: benchmark.txt + edit-mode: replace diff --git a/.github/workflows/cleanup-cache.yml b/.github/workflows/cleanup-cache.yml index 6e20b8f879..8f25fe5ef6 100644 --- a/.github/workflows/cleanup-cache.yml +++ b/.github/workflows/cleanup-cache.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Cleanup run: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0c0482ca8f..a40f07ceda 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 899c27a135..02edd57923 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 2 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0ed82dd853..c78156ca04 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 2 submodules: recursive diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 712d30dac0..862d669466 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000000..04f8c822c7 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,16 @@ +name: "Static code analysis" + +on: [pull_request] +jobs: + lint: + name: CodeQL + runs-on: ubuntu-latest + + steps: + - name: Check out the repo + uses: actions/checkout@v4 + + - name: Run CodeQL + run: | + docker run --rm -v $PWD:/app composer:2.6 sh -c \ + "composer install --profile --ignore-platform-reqs && composer check" \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1d35fec3c7..6fd4e89858 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -90,6 +90,9 @@ jobs: docker compose up -d sleep 10 + - name: Logs + run: docker compose logs appwrite + - name: Doctor run: docker compose exec -T appwrite doctor @@ -119,6 +122,14 @@ jobs: docker load --input /tmp/${{ env.IMAGE }}.tar docker compose up -d sleep 10 + + - name: Wait for Open Runtimes + timeout-minutes: 3 + run: | + while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do + echo "Waiting for Executor to come online" + sleep 1 + done - name: Run General Tests run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/General --debug @@ -142,7 +153,10 @@ jobs: Locale, Projects, Realtime, + Sites, + Proxy, Storage, + Tokens, Teams, Users, Webhooks, @@ -167,6 +181,14 @@ jobs: docker compose up -d sleep 30 + - name: Wait for Open Runtimes + timeout-minutes: 3 + run: | + while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do + echo "Waiting for Executor to come online" + sleep 1 + done + - name: Run ${{ matrix.service }} tests with Project table mode run: | echo "Using project tables" @@ -176,7 +198,7 @@ jobs: docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ - appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug + appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude=devKeys e2e_shared_mode_test: name: E2E Shared Mode Service Test @@ -199,13 +221,16 @@ jobs: Locale, Projects, Realtime, + Sites, + Proxy, Storage, Teams, Users, Webhooks, VCS, Messaging, - Migrations + Migrations, + Tokens ] tables-mode: [ 'Shared V1', @@ -229,6 +254,14 @@ jobs: docker compose up -d sleep 30 + - name: Wait for Open Runtimes + timeout-minutes: 3 + run: | + while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do + echo "Waiting for Executor to come online" + sleep 1 + done + - name: Run ${{ matrix.service }} tests with ${{ matrix.tables-mode }} table mode run: | if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then @@ -240,90 +273,90 @@ jobs: export _APP_DATABASE_SHARED_TABLES=database_db_main export _APP_DATABASE_SHARED_TABLES_V1= fi - + docker compose exec -T \ -e _APP_DATABASE_SHARED_TABLES \ -e _APP_DATABASE_SHARED_TABLES_V1 \ - appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug + appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude=devKeys - benchmarking: - name: Benchmark + e2e_dev_keys: + name: E2E Service Test (Dev Keys) runs-on: ubuntu-latest needs: setup - permissions: - pull-requests: write + strategy: + fail-fast: false steps: - - name: Checkout repository + - name: checkout uses: actions/checkout@v4 + - name: Load Cache uses: actions/cache@v4 with: key: ${{ env.CACHE_KEY }} path: /tmp/${{ env.IMAGE }}.tar fail-on-cache-miss: true + - name: Load and Start Appwrite run: | - sed -i 's/traefik/localhost/g' .env - docker load --input /tmp/${{ env.IMAGE }}.tar + docker load --input /tmp/${{ env.IMAGE }}.tar + sed -i 's/_APP_OPTIONS_ABUSE=disabled/_APP_OPTIONS_ABUSE=enabled/' .env docker compose up -d - sleep 10 - - name: Install Oha + sleep 30 + + - name: Run Projects tests with dev keys in dedicated table mode run: | - echo "deb [signed-by=/usr/share/keyrings/azlux-archive-keyring.gpg] http://packages.azlux.fr/debian/ stable main" | sudo tee /etc/apt/sources.list.d/azlux.list - sudo wget -O /usr/share/keyrings/azlux-archive-keyring.gpg https://azlux.fr/repo.gpg - sudo apt update - sudo apt install oha - - name: Benchmark PR - run: oha -z 180s http://localhost/v1/health/version -j > benchmark.json - - name: Cleaning - run: docker compose down -v - - name: Installing latest version + echo "Using project tables" + export _APP_DATABASE_SHARED_TABLES= + export _APP_DATABASE_SHARED_TABLES_V1= + + docker compose exec -T \ + -e _APP_DATABASE_SHARED_TABLES \ + -e _APP_DATABASE_SHARED_TABLES_V1 \ + appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys + + e2e_dev_keys_shared_mode: + name: E2E Shared Mode Service Test (Dev Keys) + runs-on: ubuntu-latest + needs: [ setup, check_database_changes ] + if: needs.check_database_changes.outputs.database_changed == 'true' + strategy: + fail-fast: false + matrix: + tables-mode: [ + 'Shared V1', + 'Shared V2', + ] + steps: + - name: checkout + uses: actions/checkout@v4 + + - name: Load Cache + uses: actions/cache@v4 + with: + key: ${{ env.CACHE_KEY }} + path: /tmp/${{ env.IMAGE }}.tar + fail-on-cache-miss: true + + - name: Load and Start Appwrite run: | - rm docker-compose.yml - rm .env - curl https://appwrite.io/install/compose -o docker-compose.yml - curl https://appwrite.io/install/env -o .env - sed -i 's/_APP_OPTIONS_ABUSE=enabled/_APP_OPTIONS_ABUSE=disabled/g' .env + docker load --input /tmp/${{ env.IMAGE }}.tar + sed -i 's/_APP_OPTIONS_ABUSE=disabled/_APP_OPTIONS_ABUSE=enabled/' .env docker compose up -d - sleep 10 - - name: Benchmark Latest - run: oha -z 180s http://localhost/v1/health/version -j > benchmark-latest.json - - name: Prepare comment + sleep 30 + + - name: Run Projects tests with dev keys in ${{ matrix.tables-mode }} table mode run: | - echo '## :sparkles: Benchmark results' > benchmark.txt - echo ' ' >> benchmark.txt - echo "- Requests per second: $(jq -r '.summary.requestsPerSec|tonumber?|floor|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json)" >> benchmark.txt - echo "- Requests with 200 status code: $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json)" >> benchmark.txt - echo "- P99 latency: $(jq -r '.latencyPercentiles.p99' benchmark.json )" >> benchmark.txt - echo " " >> benchmark.txt - echo " " >> benchmark.txt - echo "## :zap: Benchmark Comparison" >> benchmark.txt - echo " " >> benchmark.txt - echo "| Metric | This PR | Latest version | " >> benchmark.txt - echo "| --- | --- | --- | " >> benchmark.txt - echo "| RPS | $(jq -r '.summary.requestsPerSec|tonumber?|floor|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json) | $(jq -r '.summary.requestsPerSec|tonumber|floor|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark-latest.json) | " >> benchmark.txt - echo "| 200 | $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark.json) | $(jq -r '.statusCodeDistribution."200"|tostring|[while(length>0;.[:-3])|.[-3:]]|reverse|join(",")' benchmark-latest.json) | " >> benchmark.txt - echo "| P99 | $(jq -r '.latencyPercentiles.p99' benchmark.json ) | $(jq -r '.latencyPercentiles.p99' benchmark-latest.json ) | " >> benchmark.txt - - name: Save results - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} - with: - name: benchmark.json - path: benchmark.json - retention-days: 7 - - name: Find Comment - if: github.event.pull_request.head.repo.full_name == github.repository - uses: peter-evans/find-comment@v3 - id: fc - with: - issue-number: ${{ github.event.pull_request.number }} - comment-author: 'github-actions[bot]' - body-includes: Benchmark results - - name: Comment on PR - if: github.event.pull_request.head.repo.full_name == github.repository - uses: peter-evans/create-or-update-comment@v4 - with: - comment-id: ${{ steps.fc.outputs.comment-id }} - issue-number: ${{ github.event.pull_request.number }} - body-path: benchmark.txt - edit-mode: replace + if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then + echo "Using shared tables V1" + export _APP_DATABASE_SHARED_TABLES=database_db_main + export _APP_DATABASE_SHARED_TABLES_V1=database_db_main + elif [ "${{ matrix.tables-mode }}" == "Shared V2" ]; then + echo "Using shared tables V2" + export _APP_DATABASE_SHARED_TABLES=database_db_main + export _APP_DATABASE_SHARED_TABLES_V1= + fi + + docker compose exec -T \ + -e _APP_DATABASE_SHARED_TABLES \ + -e _APP_DATABASE_SHARED_TABLES_V1 \ + appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys diff --git a/.gitignore b/.gitignore index 0c19fd215e..600a6aeb08 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /node_modules/ /tests/resources/storage/ /tests/resources/functions/**/code.tar.gz +/tests/resources/sites/**/code.tar.gz /app/sdks/* /.idea/ !/.idea/workspace.xml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df88cfcfb9..7746ef99af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -163,6 +163,28 @@ Other containes should be named the same as their service, for example `redis` s - [Encryption](https://medium.com/searchencrypt/what-is-encryption-how-does-it-work-e8f20e340537#:~:text=Encryption%20is%20a%20process%20that,%2C%20or%20decrypt%2C%20the%20information.) - [Hashing](https://searchsqlserver.techtarget.com/definition/hashing#:~:text=Hashing%20is%20the%20transformation%20of,it%20using%20the%20original%20value.) +## Modules + +As Appwrite grows, we noticed approach of having all service endpoints in `app/controllers/api/[service].php` is not maintainable. Not only it creates massive files, it also doesnt contain all product's features such as workers or tasks. While there might still be some occurances of those controller files, we avoid it in all new development, and gradually migrate existing controllers to **HTTP modules**. + +### HTTP Endpoints + +Every endpoint file follows below structure, making it consistent with HTTP REST endpoint path: + +``` +src/Appwrite/Platform/Modules/[service]/Http/[resource]/[action].php +``` + +Tips and tricks: + +1. If endpoint doesn't have resource, use service name as resource name too +> Example: `Modules/Sites/Http/Sites/Get.php` + +2. If there are multiple resources, use then all in folder structure +> Example: `Modules/Sites/Http/Deployments/Builds/Create.php` + +3. Action can only be `Get`, `Create`, `Update`, `Delete` or `XList` + ## Architecture Appwrite's current structure is a combination of both [Monolithic](https://en.wikipedia.org/wiki/Monolithic_application) and [Microservice](https://en.wikipedia.org/wiki/Microservices) architectures. diff --git a/Dockerfile b/Dockerfile index 2f1ea6f279..30b017b573 100755 --- a/Dockerfile +++ b/Dockerfile @@ -44,12 +44,14 @@ COPY ./dev /usr/src/code/dev # Set Volumes RUN mkdir -p /storage/uploads && \ + mkdir -p /storage/imports && \ mkdir -p /storage/cache && \ mkdir -p /storage/config && \ mkdir -p /storage/certificates && \ mkdir -p /storage/functions && \ mkdir -p /storage/debug && \ chown -Rf www-data.www-data /storage/uploads && chmod -Rf 0755 /storage/uploads && \ + chown -Rf www-data.www-data /storage/imports && chmod -Rf 0755 /storage/imports && \ chown -Rf www-data.www-data /storage/cache && chmod -Rf 0755 /storage/cache && \ chown -Rf www-data.www-data /storage/config && chmod -Rf 0755 /storage/config && \ chown -Rf www-data.www-data /storage/certificates && chmod -Rf 0755 /storage/certificates && \ @@ -68,6 +70,7 @@ RUN chmod +x /usr/local/bin/doctor && \ chmod +x /usr/local/bin/sdks && \ chmod +x /usr/local/bin/specs && \ chmod +x /usr/local/bin/ssl && \ + chmod +x /usr/local/bin/screenshot && \ chmod +x /usr/local/bin/test && \ chmod +x /usr/local/bin/upgrade && \ chmod +x /usr/local/bin/vars && \ diff --git a/README-CN.md b/README-CN.md index a81d99c3c3..c79e0a1db4 100644 --- a/README-CN.md +++ b/README-CN.md @@ -72,7 +72,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:1.6.2 + appwrite/appwrite:1.7.0 ``` ### Windows @@ -84,7 +84,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:1.6.2 + appwrite/appwrite:1.7.0 ``` #### PowerShell @@ -94,7 +94,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:1.6.2 + appwrite/appwrite:1.7.0 ``` 运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。 diff --git a/README.md b/README.md index e8986e075f..435a2efd87 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,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:1.6.2 + appwrite/appwrite:1.7.0 ``` ### Windows @@ -90,7 +90,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:1.6.2 + appwrite/appwrite:1.7.0 ``` #### PowerShell @@ -100,7 +100,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:1.6.2 + appwrite/appwrite:1.7.0 ``` Once the Docker installation is complete, 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 completing the installation. diff --git a/app/cli.php b/app/cli.php index 9ade97e90c..0f0e48bf7d 100644 --- a/app/cli.php +++ b/app/cli.php @@ -30,8 +30,8 @@ use Utopia\Telemetry\Adapter\None as NoTelemetry; use function Swoole\Coroutine\run; -// Overwriting runtimes to be architecture agnostic for CLI -Config::setParam('runtimes', (new Runtimes('v4'))->getAll(supported: false)); +// overwriting runtimes to be architecture agnostic for CLI +Config::setParam('runtimes', (new Runtimes('v5'))->getAll(supported: false)); // require controllers after overwriting runtimes require_once __DIR__ . '/controllers/general.php'; diff --git a/app/config/collections/common.php b/app/config/collections/common.php index 8ca1d91b67..e77d5403d2 100644 --- a/app/config/collections/common.php +++ b/app/config/collections/common.php @@ -1101,6 +1101,28 @@ return [ 'array' => false, 'filters' => ['json', 'encrypt'], ], + [ + '$id' => ID::custom('scopes'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => true, + 'filters' => [], + ], + [ + '$id' => ID::custom('expire'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'required' => false, + 'signed' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], ], 'indexes' => [ [ @@ -1417,6 +1439,13 @@ return [ 'lengths' => [], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => ID::custom('_key_roles'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['roles'], + 'lengths' => [128], + 'orders' => [], + ], ], ], diff --git a/app/config/collections/platform.php b/app/config/collections/platform.php index ccb87f06b3..60f181df66 100644 --- a/app/config/collections/platform.php +++ b/app/config/collections/platform.php @@ -225,7 +225,7 @@ return [ '$id' => ID::custom('templates'), 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 1000000, // TODO make sure size fits + 'size' => 1_000_000, // TODO make sure size fits 'signed' => true, 'required' => false, 'default' => [], @@ -287,6 +287,17 @@ return [ 'array' => false, 'filters' => ['subQueryKeys'], ], + [ + '$id' => ID::custom('devKeys'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['subQueryDevKeys'], + ], [ '$id' => ID::custom('search'), 'type' => Database::VAR_STRING, @@ -717,6 +728,107 @@ return [ ], ], + 'devKeys' => [ + '$collection' => ID::custom(Database::METADATA), + '$id' => ID::custom('devKeys'), + 'name' => 'Dev keys', + 'attributes' => [ + [ + '$id' => ID::custom('projectInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('projectId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => 0, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('name'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('secret'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 512, // var_dump of \bin2hex(\random_bytes(128)) => string(256) doubling for encryption + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => ['encrypt'], + ], + [ + '$id' => ID::custom('expire'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('accessedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('sdks'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => true, + 'filters' => [], + ], + ], + 'indexes' => [ + [ + '$id' => ID::custom('_key_project'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['projectInternalId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_accessedAt', + 'type' => Database::INDEX_KEY, + 'attributes' => ['accessedAt'], + 'lengths' => [], + 'orders' => [], + ], + ], + ], + 'webhooks' => [ '$collection' => ID::custom(Database::METADATA), '$id' => ID::custom('webhooks'), @@ -1041,21 +1153,10 @@ return [ 'filters' => [], ], [ - '$id' => ID::custom('resourceType'), + '$id' => ID::custom('type'), // 'api', 'redirect', 'deployment' (site or function) 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 100, - 'signed' => true, - 'required' => true, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('resourceInternalId'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => Database::LENGTH_KEY, + 'size' => 32, 'signed' => true, 'required' => false, 'default' => null, @@ -1063,13 +1164,101 @@ return [ 'filters' => [], ], [ - '$id' => ID::custom('resourceId'), + '$id' => ID::custom('trigger'), // 'manual', 'deployment', '' (empty) + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('redirectUrl'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('redirectStatusCode'), + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentResourceType'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentId'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => Database::LENGTH_KEY, 'signed' => true, 'required' => false, - 'default' => null, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentResourceId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentResourceInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentVcsProviderBranch'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => '', 'array' => false, 'filters' => [], ], @@ -1095,6 +1284,17 @@ return [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('search'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('owner'), 'type' => Database::VAR_STRING, @@ -1119,6 +1319,13 @@ return [ ], ], 'indexes' => [ + [ + '$id' => ID::custom('_key_search'), + 'type' => Database::INDEX_FULLTEXT, + 'attributes' => ['search'], + 'lengths' => [], + 'orders' => [], + ], [ '$id' => ID::custom('_key_domain'), 'type' => Database::INDEX_UNIQUE, @@ -1141,24 +1348,59 @@ return [ 'orders' => [Database::ORDER_ASC], ], [ - '$id' => '_key_resourceInternalId', + '$id' => '_key_type', 'type' => Database::INDEX_KEY, - 'attributes' => ['resourceInternalId'], + 'attributes' => ['type'], + 'lengths' => [32], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_trigger', + 'type' => Database::INDEX_KEY, + 'attributes' => ['trigger'], + 'lengths' => [32], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_deploymentResourceType', + 'type' => Database::INDEX_KEY, + 'attributes' => ['deploymentResourceType'], + 'lengths' => [32], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_deploymentResourceId', + 'type' => Database::INDEX_KEY, + 'attributes' => ['deploymentResourceId'], 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], [ - '$id' => '_key_resourceId', + '$id' => '_key_deploymentResourceInternalId', 'type' => Database::INDEX_KEY, - 'attributes' => ['resourceId'], + 'attributes' => ['deploymentResourceInternalId'], 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], [ - '$id' => '_key_resourceType', + '$id' => '_key_deploymentId', 'type' => Database::INDEX_KEY, - 'attributes' => ['resourceType'], - 'lengths' => [], + 'attributes' => ['deploymentId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_deploymentInternalId', + 'type' => Database::INDEX_KEY, + 'attributes' => ['deploymentInternalId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_deploymentVcsProviderBranch', + 'type' => Database::INDEX_KEY, + 'attributes' => ['deploymentVcsProviderBranch'], + 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], [ @@ -1178,7 +1420,7 @@ return [ [ '$id' => ID::custom('_key_piid_riid_rt'), 'type' => Database::INDEX_KEY, - 'attributes' => ['projectInternalId', 'resourceInternalId', 'resourceType'], + 'attributes' => ['projectInternalId', 'deploymentInternalId', 'deploymentResourceType'], 'lengths' => [], 'orders' => [], ], @@ -1648,5 +1890,5 @@ return [ 'name' => 'vcsCommentLocks', 'attributes' => [], 'indexes' => [] - ] + ], ]; diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 4844ad16d3..48a0938a1c 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -569,7 +569,7 @@ return [ 'filters' => [], ], [ - '$id' => ID::custom('deployment'), + '$id' => ID::custom('deploymentId'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => Database::LENGTH_KEY, @@ -579,6 +579,61 @@ return [ 'array' => false, 'filters' => [], ], + [ + '$id' => ID::custom('deploymentCreatedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('latestDeploymentId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('latestDeploymentInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('latestDeploymentCreatedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('latestDeploymentStatus'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('vars'), 'type' => Database::VAR_STRING, @@ -674,7 +729,7 @@ return [ 'size' => 8, 'signed' => true, 'required' => false, - 'default' => 'v4', + 'default' => 'v5', 'array' => false, 'filters' => [], ], @@ -708,7 +763,7 @@ return [ 'size' => 128, 'signed' => false, 'required' => false, - 'default' => APP_FUNCTION_SPECIFICATION_DEFAULT, + 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, 'filters' => [], ], [ @@ -788,15 +843,449 @@ return [ 'orders' => [Database::ORDER_ASC], ], [ - '$id' => ID::custom('_key_deployment'), + '$id' => ID::custom('_key_deploymentId'), 'type' => Database::INDEX_KEY, - 'attributes' => ['deployment'], + 'attributes' => ['deploymentId'], 'lengths' => [], 'orders' => [Database::ORDER_ASC], ] ], ], + 'sites' => [ + '$collection' => ID::custom(Database::METADATA), + '$id' => ID::custom('sites'), + 'name' => 'Sites', + 'attributes' => [ + [ + '$id' => ID::custom('name'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('enabled'), + 'type' => Database::VAR_BOOLEAN, + 'signed' => true, + 'size' => 0, + 'format' => '', + 'filters' => [], + 'required' => true, + 'array' => false, + ], + [ + '$id' => ID::custom('live'), + 'type' => Database::VAR_BOOLEAN, + 'signed' => true, + 'size' => 0, + 'format' => '', + 'filters' => [], + 'required' => true, + 'array' => false, + ], + [ + '$id' => ID::custom('installationId'), + 'type' => Database::VAR_STRING, + 'signed' => true, + 'size' => Database::LENGTH_KEY, + 'format' => '', + 'filters' => [], + 'required' => false, + 'array' => false, + ], + [ + '$id' => ID::custom('installationInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('providerRepositoryId'), + 'type' => Database::VAR_STRING, + 'signed' => true, + 'size' => Database::LENGTH_KEY, + 'format' => '', + 'filters' => [], + 'required' => false, + 'array' => false, + ], + [ + '$id' => ID::custom('repositoryId'), + 'type' => Database::VAR_STRING, + 'signed' => true, + 'size' => Database::LENGTH_KEY, + 'format' => '', + 'filters' => [], + 'required' => false, + 'array' => false, + ], + [ + '$id' => ID::custom('repositoryInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('providerBranch'), + 'type' => Database::VAR_STRING, + 'signed' => true, + 'size' => Database::LENGTH_KEY, + 'format' => '', + 'filters' => [], + 'required' => false, + 'array' => false, + ], + [ + '$id' => ID::custom('providerRootDirectory'), + 'type' => Database::VAR_STRING, + 'signed' => true, + 'size' => Database::LENGTH_KEY, + 'format' => '', + 'filters' => [], + 'required' => false, + 'array' => false, + ], + [ + '$id' => ID::custom('providerSilentMode'), + 'type' => Database::VAR_BOOLEAN, + 'signed' => true, + 'size' => 0, + 'format' => '', + 'filters' => [], + 'required' => false, + 'default' => false, + 'array' => false, + ], + [ + '$id' => ID::custom('logging'), + 'type' => Database::VAR_BOOLEAN, + 'signed' => true, + 'size' => 0, + 'format' => '', + 'filters' => [], + 'required' => true, + 'array' => false, + ], + [ + '$id' => ID::custom('framework'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + 'array' => false, + '$id' => ID::custom('outputDirectory'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'filters' => [], + ], + [ + 'array' => false, + '$id' => ID::custom('buildCommand'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'filters' => [], + ], + [ + 'array' => false, + '$id' => ID::custom('installCommand'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'filters' => [], + ], + [ + '$id' => ID::custom('fallbackFile'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentCreatedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('deploymentScreenshotLight'), // File ID from 'screenshots' Console bucket + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('deploymentScreenshotDark'), // File ID from 'screenshots' Console bucket + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('latestDeploymentId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('latestDeploymentInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('latestDeploymentCreatedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('latestDeploymentStatus'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('vars'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['subQueryVariables'], + ], + [ + '$id' => ID::custom('varsProject'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['subQueryProjectVariables'], + ], + [ + '$id' => ID::custom('timeout'), + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('search'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + 'array' => false, + '$id' => ID::custom('specification'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 128, + 'signed' => false, + 'required' => false, + 'default' => APP_COMPUTE_SPECIFICATION_DEFAULT, + 'filters' => [], + ], + [ + '$id' => ID::custom('buildRuntime'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 2048, + 'signed' => true, + 'required' => true, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('adapter'), // ssr or static; named this way as it's a term in SSR frameworks + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + ], + 'indexes' => [ + [ + '$id' => ID::custom('_key_search'), + 'type' => Database::INDEX_FULLTEXT, + 'attributes' => ['search'], + 'lengths' => [], + 'orders' => [], + ], + [ + '$id' => ID::custom('_key_name'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['name'], + 'lengths' => [256], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_enabled'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['enabled'], + 'lengths' => [], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_installationId'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['installationId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_installationInternalId'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['installationInternalId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_providerRepositoryId'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['providerRepositoryId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_repositoryId'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['repositoryId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_repositoryInternalId'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['repositoryInternalId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_framework'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['framework'], + 'lengths' => [64], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_deploymentId'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['deploymentId'], + 'lengths' => [], + 'orders' => [Database::ORDER_ASC], + ] + ], + ], 'deployments' => [ '$collection' => ID::custom(Database::METADATA), '$id' => ID::custom('deployments'), @@ -835,28 +1324,6 @@ return [ 'array' => false, 'filters' => [], ], - [ - '$id' => ID::custom('buildInternalId'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => Database::LENGTH_KEY, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('buildId'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => Database::LENGTH_KEY, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], [ 'array' => false, '$id' => ID::custom('entrypoint'), @@ -870,20 +1337,31 @@ return [ ], [ 'array' => false, - '$id' => ID::custom('commands'), + '$id' => ID::custom('buildCommands'), 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 2048, + 'size' => 16384, 'signed' => true, 'required' => false, 'default' => null, 'filters' => [], ], [ - '$id' => ID::custom('path'), + 'array' => false, + '$id' => ID::custom('buildOutput'), 'type' => Database::VAR_STRING, 'format' => '', - 'size' => 2048, + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'filters' => [], + ], + [ + '$id' => ID::custom('sourcePath'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, 'signed' => true, 'required' => false, 'default' => null, @@ -1073,18 +1551,18 @@ return [ 'array' => false, ], [ - '$id' => ID::custom('size'), + '$id' => ID::custom('sourceSize'), 'type' => Database::VAR_INTEGER, 'format' => '', - 'size' => 0, - 'signed' => true, + 'size' => 8, + 'signed' => false, 'required' => false, 'default' => null, 'array' => false, 'filters' => [], ], [ - '$id' => ID::custom('metadata'), + '$id' => ID::custom('sourceMetadata'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => 16384, // https://tools.ietf.org/html/rfc4288#section-4.2 @@ -1095,7 +1573,7 @@ return [ 'filters' => ['json'], ], [ - '$id' => ID::custom('chunksTotal'), + '$id' => ID::custom('sourceChunksTotal'), 'type' => Database::VAR_INTEGER, 'format' => '', 'size' => 0, @@ -1106,7 +1584,7 @@ return [ 'filters' => [], ], [ - '$id' => ID::custom('chunksUploaded'), + '$id' => ID::custom('sourceChunksUploaded'), 'type' => Database::VAR_INTEGER, 'format' => '', 'size' => 0, @@ -1116,17 +1594,6 @@ return [ 'array' => false, 'filters' => [], ], - [ - '$id' => ID::custom('search'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 16384, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], [ '$id' => ID::custom('activate'), 'type' => Database::VAR_BOOLEAN, @@ -1137,6 +1604,138 @@ return [ 'default' => false, 'array' => false, 'filters' => [], + ], + [ + '$id' => ID::custom('screenshotLight'), // File ID from 'screenshots' Console bucket + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('screenshotDark'), // File ID from 'screenshots' Console bucket + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 32, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('buildStartedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('buildEndedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('buildDuration'), + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('buildSize'), + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 8, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('totalSize'), + 'type' => Database::VAR_INTEGER, + 'format' => '', + 'size' => 8, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('status'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16, + 'signed' => true, + 'required' => false, + 'default' => 'waiting', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('buildPath'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('buildLogs'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 1000000, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('adapter'), // ssr or static; named this way as it's a term in SSR frameworks + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16, + 'signed' => true, + 'required' => false, + 'default' => '', + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('fallbackFile'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], ] ], 'indexes' => [ @@ -1155,23 +1754,30 @@ return [ 'orders' => [Database::ORDER_ASC], ], [ - '$id' => ID::custom('_key_search'), - 'type' => Database::INDEX_FULLTEXT, - 'attributes' => ['search'], - 'lengths' => [], - 'orders' => [], - ], - [ - '$id' => ID::custom('_key_size'), + '$id' => ID::custom('_key_sourceSize'), 'type' => Database::INDEX_KEY, - 'attributes' => ['size'], + 'attributes' => ['sourceSize'], 'lengths' => [], 'orders' => [Database::ORDER_ASC], ], [ - '$id' => ID::custom('_key_buildId'), + '$id' => ID::custom('_key_buildSize'), 'type' => Database::INDEX_KEY, - 'attributes' => ['buildId'], + 'attributes' => ['buildSize'], + 'lengths' => [], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_totalSize'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['totalSize'], + 'lengths' => [], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_buildDuration'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['buildDuration'], 'lengths' => [], 'orders' => [Database::ORDER_ASC], ], @@ -1183,165 +1789,30 @@ return [ 'orders' => [Database::ORDER_ASC], ], [ - '$id' => ID::custom('_key_resource_internal_id'), + '$id' => ID::custom('_key_type'), 'type' => Database::INDEX_KEY, - 'attributes' => ['resourceInternalId'], - 'lengths' => [], - 'orders' => [], - ], - ], - ], - - 'builds' => [ - '$collection' => ID::custom(Database::METADATA), - '$id' => ID::custom('builds'), - 'name' => 'Builds', - 'attributes' => [ - [ - '$id' => ID::custom('startTime'), - 'type' => Database::VAR_DATETIME, - 'format' => '', - 'size' => 0, - 'signed' => false, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => ['datetime'], - ], - [ - '$id' => ID::custom('endTime'), - 'type' => Database::VAR_DATETIME, - 'format' => '', - 'size' => 0, - 'signed' => false, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => ['datetime'], - ], - [ - '$id' => ID::custom('duration'), - 'type' => Database::VAR_INTEGER, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('size'), - 'type' => Database::VAR_INTEGER, - 'format' => '', - 'size' => 0, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('deploymentInternalId'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => Database::LENGTH_KEY, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('deploymentId'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => Database::LENGTH_KEY, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('runtime'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 2048, - 'signed' => true, - 'required' => true, - 'default' => '', - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('status'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 256, - 'signed' => true, - 'required' => true, - 'default' => 'processing', - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('path'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 2048, - 'signed' => true, - 'required' => false, - 'default' => '', - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('logs'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 1000000, - 'signed' => true, - 'required' => false, - 'default' => '', - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('sourceType'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 2048, - 'signed' => true, - 'required' => true, - 'default' => 'local', - 'array' => false, - 'filters' => [], - ], - [ - '$id' => ID::custom('source'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 2048, - 'signed' => true, - 'required' => true, - 'default' => '', - 'array' => false, - 'filters' => [], - ] - ], - 'indexes' => [ - [ - '$id' => ID::custom('_key_deployment'), - 'type' => Database::INDEX_KEY, - 'attributes' => ['deploymentId'], - 'lengths' => [Database::LENGTH_KEY], + 'attributes' => ['type'], + 'lengths' => [32], 'orders' => [Database::ORDER_ASC], ], [ - '$id' => ID::custom('_key_deployment_internal_id'), + '$id' => ID::custom('_key_status'), 'type' => Database::INDEX_KEY, - 'attributes' => ['deploymentInternalId'], + 'attributes' => ['status'], + 'lengths' => [16], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => ID::custom('_key_resourceId_resourceType'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['resourceId', 'resourceType'], + 'lengths' => [], + 'orders' => [], + ], + [ + '$id' => ID::custom('_key_resource_internal_id'), + 'type' => Database::INDEX_KEY, + 'attributes' => ['resourceInternalId'], 'lengths' => [], 'orders' => [], ], @@ -1354,7 +1825,7 @@ return [ 'name' => 'Executions', 'attributes' => [ [ - '$id' => ID::custom('functionInternalId'), + '$id' => ID::custom('resourceInternalId'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => Database::LENGTH_KEY, @@ -1365,7 +1836,18 @@ return [ 'filters' => [], ], [ - '$id' => ID::custom('functionId'), + '$id' => ID::custom('resourceId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('resourceType'), 'type' => Database::VAR_STRING, 'format' => '', 'size' => Database::LENGTH_KEY, @@ -1507,17 +1989,6 @@ return [ 'array' => false, 'filters' => ['json'], ], - [ - '$id' => ID::custom('search'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 16384, - 'signed' => true, - 'required' => false, - 'default' => null, - 'array' => false, - 'filters' => [], - ], [ '$id' => ID::custom('scheduledAt'), 'type' => Database::VAR_DATETIME, @@ -1554,19 +2025,12 @@ return [ ], 'indexes' => [ [ - '$id' => ID::custom('_key_function'), + '$id' => ID::custom('_key_resource'), 'type' => Database::INDEX_KEY, - 'attributes' => ['functionId'], + 'attributes' => ['resourceInternalId', 'resourceType', 'resourceId'], 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], - [ - '$id' => ID::custom('_fulltext_search'), - 'type' => Database::INDEX_FULLTEXT, - 'attributes' => ['search'], - 'lengths' => [], - 'orders' => [], - ], [ '$id' => ID::custom('_key_trigger'), 'type' => Database::INDEX_KEY, @@ -1619,7 +2083,7 @@ return [ [ '$id' => ID::custom('_key_function_internal_id'), 'type' => Database::INDEX_KEY, - 'attributes' => ['functionInternalId'], + 'attributes' => ['resourceInternalId'], 'lengths' => [], 'orders' => [], ], @@ -1686,6 +2150,17 @@ return [ 'array' => false, 'filters' => ['encrypt'] ], + [ + '$id' => ID::custom('secret'), + 'type' => Database::VAR_BOOLEAN, + 'format' => '', + 'size' => 0, + 'signed' => true, + 'required' => false, + 'default' => false, + 'array' => false, + 'filters' => [], + ], [ '$id' => ID::custom('search'), 'type' => Database::VAR_STRING, @@ -1811,6 +2286,17 @@ return [ 'array' => false, 'filters' => ['json', 'encrypt'], ], + [ + '$id' => ID::custom('options'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 65536, + 'signed' => true, + 'required' => false, + 'default' => [], + 'array' => false, + 'filters' => ['json'], + ], [ '$id' => ID::custom('resources'), 'type' => Database::VAR_STRING, @@ -1865,7 +2351,29 @@ return [ 'default' => null, 'array' => false, 'filters' => [], - ] + ], + [ + '$id' => ID::custom('resourceId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('resourceType'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => [], + ], ], 'indexes' => [ [ @@ -1889,6 +2397,13 @@ return [ 'lengths' => [Database::LENGTH_KEY], 'orders' => [Database::ORDER_ASC], ], + [ + '$id' => '_key_resource_id', + 'type' => Database::INDEX_KEY, + 'attributes' => ['resourceId'], + 'lengths' => [Database::LENGTH_KEY], + 'orders' => [Database::ORDER_DESC], + ], [ '$id' => ID::custom('_fulltext_search'), 'type' => Database::INDEX_FULLTEXT, @@ -1898,4 +2413,101 @@ return [ ] ], ], + + 'resourceTokens' => [ + '$collection' => ID::custom(Database::METADATA), + '$id' => ID::custom('resourceTokens'), + 'name' => 'Resource Tokens', + 'attributes' => [ + [ + '$id' => ID::custom('resourceId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('resourceInternalId'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => Database::LENGTH_KEY, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('resourceType'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 100, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => [], + ], + [ + '$id' => ID::custom('secret'), + 'type' => Database::VAR_STRING, + 'format' => '', + 'size' => 512, + 'signed' => true, + 'required' => true, + 'default' => null, + 'array' => false, + 'filters' => ['encrypt'], + ], + [ + '$id' => ID::custom('expire'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 255, + 'signed' => true, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + [ + '$id' => ID::custom('accessedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], + ], + 'indexes' => [ + [ + '$id' => '_key_expiry_date', + 'type' => Database::INDEX_KEY, + 'attributes' => ['expire'], + 'lengths' => [], + 'orders' => [Database::ORDER_ASC], + ], + [ + '$id' => '_key_accessedAt', + 'type' => Database::INDEX_KEY, + 'attributes' => ['accessedAt'], + 'lengths' => [], + 'orders' => [], + ], + [ + '$id' => '_key_resourceInternalId_resourceType', + 'type' => Database::INDEX_KEY, + 'attributes' => ['resourceInternalId', 'resourceType'], + 'lengths' => [], + 'orders' => [], + ], + ], + ], ]; diff --git a/app/config/errors.php b/app/config/errors.php index eb5a6cbbbb..6d9d29a8ea 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -375,6 +375,13 @@ return [ 'code' => 409, ], + /** Console */ + Exception::RESOURCE_ALREADY_EXISTS => [ + 'name' => Exception::RESOURCE_ALREADY_EXISTS, + 'description' => 'Resource with the requested ID already exists. Please choose a different ID and try again.', + 'code' => 409, + ], + /** Membership */ Exception::MEMBERSHIP_NOT_FOUND => [ 'name' => Exception::MEMBERSHIP_NOT_FOUND, @@ -481,6 +488,23 @@ return [ 'code' => 403, ], + /** Tokens */ + Exception::TOKEN_NOT_FOUND => [ + 'name' => Exception::TOKEN_NOT_FOUND, + 'description' => 'The requested file token could not be found.', + 'code' => 404, + ], + Exception::TOKEN_EXPIRED => [ + 'name' => Exception::TOKEN_EXPIRED, + 'description' => 'The requested file token has expired.', + 'code' => 401, + ], + Exception::TOKEN_RESOURCE_TYPE_INVALID => [ + 'name' => Exception::TOKEN_RESOURCE_TYPE_INVALID, + 'description' => 'The resource type for the token is invalid.', + 'code' => 400, + ], + /** VCS */ Exception::INSTALLATION_NOT_FOUND => [ 'name' => Exception::INSTALLATION_NOT_FOUND, @@ -520,7 +544,7 @@ return [ 'code' => 404, ], Exception::FUNCTION_ENTRYPOINT_MISSING => [ - 'name' => Exception::FUNCTION_RUNTIME_UNSUPPORTED, + 'name' => Exception::FUNCTION_ENTRYPOINT_MISSING, 'description' => 'Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".', 'code' => 404, ], @@ -534,6 +558,28 @@ return [ 'description' => 'Function Template with the requested ID could not be found.', 'code' => 404, ], + Exception::FUNCTION_RUNTIME_NOT_DETECTED => [ + 'name' => Exception::FUNCTION_RUNTIME_NOT_DETECTED, + 'description' => 'Function runtime could not be detected.', + 'code' => 400, + ], + Exception::FUNCTION_EXECUTE_PERMISSION_MISSING => [ + 'name' => Exception::FUNCTION_EXECUTE_PERMISSION_MISSING, + 'description' => 'To execute function using domain, execute permissions must include "any" or "guests".', + 'code' => 401, + ], + + /** Sites */ + Exception::SITE_NOT_FOUND => [ + 'name' => Exception::SITE_NOT_FOUND, + 'description' => 'Site with the requested ID could not be found.', + 'code' => 404, + ], + Exception::SITE_TEMPLATE_NOT_FOUND => [ + 'name' => Exception::SITE_TEMPLATE_NOT_FOUND, + 'description' => 'Site Template with the requested ID could not be found.', + 'code' => 404, + ], /** Builds */ Exception::BUILD_NOT_FOUND => [ @@ -556,6 +602,16 @@ return [ 'description' => 'Build with the requested ID is already completed and cannot be canceled.', 'code' => 400, ], + Exception::BUILD_CANCELED => [ + 'name' => Exception::BUILD_CANCELED, + 'description' => 'Build with the requested ID has been canceled.', + 'code' => 400, + ], + Exception::BUILD_FAILED => [ + 'name' => Exception::BUILD_FAILED, + 'description' => 'Build with the requested ID failed. Please check the logs for more information.', + 'code' => 400, + ], /** Deployments */ Exception::DEPLOYMENT_NOT_FOUND => [ @@ -577,6 +633,13 @@ return [ 'code' => 400, ], + /** Logs */ + Exception::LOG_NOT_FOUND => [ + 'name' => Exception::LOG_NOT_FOUND, + 'description' => 'Log with the requested ID could not be found.', + 'code' => 404, + ], + /** Databases */ Exception::DATABASE_NOT_FOUND => [ 'name' => Exception::DATABASE_NOT_FOUND, @@ -806,7 +869,7 @@ return [ Exception::RULE_VERIFICATION_FAILED => [ 'name' => Exception::RULE_VERIFICATION_FAILED, 'description' => 'Domain verification failed. Please check if your DNS records are correct and try again.', - 'code' => 401, + 'code' => 400, 'publish' => true ], Exception::PROJECT_SMTP_CONFIG_INVALID => [ @@ -849,6 +912,11 @@ return [ 'description' => 'Variable with the same ID already exists in this project. Try again with a different ID.', 'code' => 409, ], + Exception::VARIABLE_CANNOT_UNSET_SECRET => [ + 'name' => Exception::VARIABLE_CANNOT_UNSET_SECRET, + 'description' => 'Secret variables cannot be marked as non-secret. Please re-create the variable if this is your intention.', + 'code' => 400, + ], Exception::GRAPHQL_NO_QUERY => [ 'name' => Exception::GRAPHQL_NO_QUERY, 'description' => 'Param "query" is not optional.', diff --git a/app/config/events.php b/app/config/events.php index 5378502faf..0bfddf4f1f 100644 --- a/app/config/events.php +++ b/app/config/events.php @@ -217,6 +217,34 @@ return [ ], ] ], + 'sites' => [ + '$model' => Response::MODEL_SITE, + '$resource' => true, + '$description' => 'This event triggers on any sites event.', + 'deployments' => [ + '$model' => Response::MODEL_DEPLOYMENT, + '$resource' => true, + '$description' => 'This event triggers on any deployments event.', + 'create' => [ + '$description' => 'This event triggers when a deployment is created.', + ], + 'delete' => [ + '$description' => 'This event triggers when a deployment is deleted.' + ], + 'update' => [ + '$description' => 'This event triggers when a deployment is updated.' + ], + ], + 'create' => [ + '$description' => 'This event triggers when a site is created.' + ], + 'delete' => [ + '$description' => 'This event triggers when a site is deleted.', + ], + 'update' => [ + '$description' => 'This event triggers when a site is updated.', + ] + ], 'functions' => [ '$model' => Response::MODEL_FUNCTION, '$resource' => true, diff --git a/app/config/frameworks.php b/app/config/frameworks.php new file mode 100644 index 0000000000..f4d8ec7ffa --- /dev/null +++ b/app/config/frameworks.php @@ -0,0 +1,312 @@ + [ + 'key' => 'analog', + 'name' => 'Analog', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/analog/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/analog/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist/analog', + 'startCommand' => 'bash helpers/analog/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist/analog/public', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.html' + ] + ] + ], + 'angular' => [ + 'key' => 'angular', + 'name' => 'Angular', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/angular/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/angular/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist/angular', + 'startCommand' => 'bash helpers/angular/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist/angular/browser', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.csr.html' + ] + ] + ], + 'nextjs' => [ + 'key' => 'nextjs', + 'name' => 'Next.js', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/next-js/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/next-js/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './.next', + 'startCommand' => 'bash helpers/next-js/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './out', + 'startCommand' => 'bash helpers/server.sh', + ] + ] + ], + 'react' => [ + 'key' => 'react', + 'name' => 'React', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.html' + ] + ] + ], + 'nuxt' => [ + 'key' => 'nuxt', + 'name' => 'Nuxt', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/nuxt/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/nuxt/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './.output', + 'startCommand' => 'bash helpers/nuxt/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run generate', + 'installCommand' => 'npm install', + 'outputDirectory' => './output/public', + 'startCommand' => 'bash helpers/server.sh', + ] + ] + ], + 'vue' => [ + 'key' => 'vue', + 'name' => 'Vue.js', + 'screenshotSleep' => 5000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.html' + ] + ] + ], + 'sveltekit' => [ + 'key' => 'sveltekit', + 'name' => 'SvelteKit', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/sveltekit/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/sveltekit/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './build', + 'startCommand' => 'bash helpers/sveltekit/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './build', + 'startCommand' => 'bash helpers/server.sh', + ] + ] + ], + 'astro' => [ + 'key' => 'astro', + 'name' => 'Astro', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/astro/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/astro/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/astro/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + ] + ] + ], + 'remix' => [ + 'key' => 'remix', + 'name' => 'Remix', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'bundleCommand' => 'bash /usr/local/server/helpers/remix/bundle.sh', + 'envCommand' => 'source /usr/local/server/helpers/remix/env.sh', + 'adapters' => [ + 'ssr' => [ + 'key' => 'ssr', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './build', + 'startCommand' => 'bash helpers/remix/server.sh', + ], + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './build/client', + 'startCommand' => 'bash helpers/server.sh', + ] + ] + ], + 'lynx' => [ + 'key' => 'lynx', + 'name' => 'Lynx', + 'screenshotSleep' => 5000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.html' + ] + ] + ], + 'flutter' => [ + 'key' => 'flutter', + 'name' => 'Flutter', + 'screenshotSleep' => 5000, + 'buildRuntime' => 'flutter-3.29', + 'runtimes' => getVersions($templateRuntimes['FLUTTER']['versions'], 'flutter'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'flutter build web --release -t lib/main.dart', + 'installCommand' => 'flutter pub get', + 'outputDirectory' => './build/web', + 'startCommand' => 'bash helpers/server.sh', + ], + ], + ], + 'react-native' => [ + 'key' => 'react-native', + 'name' => 'React Native', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + 'fallbackFile' => 'index.html' + ] + ] + ], + 'vite' => [ + 'key' => 'vite', + 'name' => 'Vite', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => 'npm run build', + 'installCommand' => 'npm install', + 'outputDirectory' => './dist', + 'startCommand' => 'bash helpers/server.sh', + ], + ] + ], + 'other' => [ + 'key' => 'other', + 'name' => 'Other', + 'screenshotSleep' => 3000, + 'buildRuntime' => 'node-22', + 'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'), + 'adapters' => [ + 'static' => [ + 'key' => 'static', + 'buildCommand' => '', + 'installCommand' => '', + 'outputDirectory' => './', + 'startCommand' => 'bash helpers/server.sh', + ], + ] + ], +]; diff --git a/app/config/locale/templates/email-base-styled.tpl b/app/config/locale/templates/email-base-styled.tpl index 4d6972389e..f6d3e8cd63 100644 --- a/app/config/locale/templates/email-base-styled.tpl +++ b/app/config/locale/templates/email-base-styled.tpl @@ -79,7 +79,7 @@ + + +
+ + +Powered by
+ + + +