Merge remote-tracking branch 'origin/master' into feat-graphql-support
# Conflicts: # app/controllers/api/account.php # app/controllers/api/graphql.php # app/controllers/api/projects.php # app/controllers/api/users.php # app/controllers/general.php # app/http.php # app/init.php # composer.lock # src/Appwrite/Utopia/Response.php
@@ -1,8 +1,6 @@
|
||||
app/db/SQL
|
||||
node_modules
|
||||
storage
|
||||
public/scripts
|
||||
public/styles
|
||||
.git
|
||||
.idea
|
||||
.cd .babelrc
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
_APP_ENV=production
|
||||
_APP_ENV=development
|
||||
_APP_LOCALE=en
|
||||
_APP_WORKER_PER_CORE=6
|
||||
_APP_CONSOLE_WHITELIST_ROOT=disabled
|
||||
_APP_CONSOLE_WHITELIST_EMAILS=
|
||||
_APP_CONSOLE_WHITELIST_IPS=
|
||||
@@ -15,11 +15,23 @@ _APP_DOMAIN=demo.appwrite.io
|
||||
_APP_DOMAIN_TARGET=demo.appwrite.io
|
||||
_APP_REDIS_HOST=redis
|
||||
_APP_REDIS_PORT=6379
|
||||
_APP_REDIS_PASS=
|
||||
_APP_REDIS_USER=
|
||||
_APP_DB_HOST=mariadb
|
||||
_APP_DB_PORT=3306
|
||||
_APP_DB_SCHEMA=appwrite
|
||||
_APP_DB_USER=user
|
||||
_APP_DB_PASS=password
|
||||
_APP_DB_ROOT_PASS=rootsecretpassword
|
||||
_APP_STORAGE_DEVICE=Local
|
||||
_APP_STORAGE_S3_ACCESS_KEY=
|
||||
_APP_STORAGE_S3_SECRET=
|
||||
_APP_STORAGE_S3_REGION=us-eas-1
|
||||
_APP_STORAGE_S3_BUCKET=
|
||||
_APP_STORAGE_DO_SPACES_ACCESS_KEY=
|
||||
_APP_STORAGE_DO_SPACES_SECRET=
|
||||
_APP_STORAGE_DO_SPACES_REGION=us-eas-1
|
||||
_APP_STORAGE_DO_SPACES_BUCKET=
|
||||
_APP_STORAGE_ANTIVIRUS=disabled
|
||||
_APP_STORAGE_ANTIVIRUS_HOST=clamav
|
||||
_APP_STORAGE_ANTIVIRUS_PORT=3310
|
||||
@@ -32,14 +44,25 @@ _APP_SMTP_PORT=1025
|
||||
_APP_SMTP_SECURE=
|
||||
_APP_SMTP_USERNAME=
|
||||
_APP_SMTP_PASSWORD=
|
||||
_APP_STORAGE_LIMIT=10000000
|
||||
_APP_STORAGE_LIMIT=30000000
|
||||
_APP_FUNCTIONS_SIZE_LIMIT=30000000
|
||||
_APP_FUNCTIONS_TIMEOUT=900
|
||||
_APP_FUNCTIONS_BUILD_TIMEOUT=900
|
||||
_APP_FUNCTIONS_CONTAINERS=10
|
||||
_APP_FUNCTIONS_CPUS=1
|
||||
_APP_FUNCTIONS_MEMORY=256
|
||||
_APP_FUNCTIONS_MEMORY_SWAP=256
|
||||
_APP_FUNCTIONS_CPUS=0
|
||||
_APP_FUNCTIONS_MEMORY=0
|
||||
_APP_FUNCTIONS_MEMORY_SWAP=0
|
||||
_APP_FUNCTIONS_INACTIVE_THRESHOLD=60
|
||||
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
|
||||
_APP_EXECUTOR_SECRET=your-secret-key
|
||||
_APP_MAINTENANCE_INTERVAL=86400
|
||||
_APP_MAINTENANCE_RETENTION_EXECUTION=1209600
|
||||
_APP_MAINTENANCE_RETENTION_ABUSE=86400
|
||||
_APP_MAINTENANCE_RETENTION_AUDIT=1209600
|
||||
_APP_USAGE_AGGREGATION_INTERVAL=30
|
||||
_APP_USAGE_STATS=enabled
|
||||
_APP_LOGGING_PROVIDER=
|
||||
_APP_LOGGING_CONFIG=
|
||||
DOCKERHUB_PULL_USERNAME=
|
||||
DOCKERHUB_PULL_PASSWORD=
|
||||
DOCKERHUB_PULL_EMAIL=
|
||||
@@ -1,10 +1,24 @@
|
||||
app/config/* linguist-detectable=false
|
||||
app/config/* linguist-detectable=false
|
||||
app/config/*/* linguist-detectable=false
|
||||
app/config/*/*/* linguist-detectable=false
|
||||
app/config/*/*/*/* linguist-detectable=false
|
||||
app/views/* linguist-detectable=false
|
||||
app/views/*/* linguist-detectable=false
|
||||
app/views/*/*/* linguist-detectable=false
|
||||
app/views/*/*/*/* linguist-detectable=false
|
||||
app/controllers/* linguist-detectable=false
|
||||
app/controllers/*/* linguist-detectable=false
|
||||
app/controllers/*/*/* linguist-detectable=false
|
||||
app/controllers/*/*/*/* linguist-detectable=false
|
||||
app/controllers/*/*/*/*/* linguist-detectable=false
|
||||
src/* linguist-detectable=false
|
||||
src/*/* linguist-detectable=false
|
||||
src/*/*/* linguist-detectable=false
|
||||
src/*/*/*/* linguist-detectable=false
|
||||
src/*/*/*/*/* linguist-detectable=false
|
||||
tests/* linguist-detectable=false
|
||||
tests/*/* linguist-detectable=false
|
||||
tests/*/*/* linguist-detectable=false
|
||||
tests/*/*/*/* linguist-detectable=false
|
||||
tests/*/*/*/*/* linguist-detectable=false
|
||||
tests/*/*/*/*/* linguist-detectable=false
|
||||
tests/*/*/*/*/*/* linguist-detectable=false
|
||||
|
||||
@@ -37,6 +37,9 @@ 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
|
||||
- Version 0.9.x
|
||||
- Version 0.8.x
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
name: "Tests"
|
||||
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
tests:
|
||||
name: Unit & E2E
|
||||
runs-on: self-hosted
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
- name: Build Appwrite
|
||||
# Upstream bug causes buildkit pulls to fail so prefetch base images
|
||||
# https://github.com/moby/moby/issues/41864
|
||||
run: |
|
||||
echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
|
||||
docker pull composer:2.0
|
||||
docker pull php:8.0-cli-alpine
|
||||
docker compose build --progress=plain
|
||||
docker compose up -d
|
||||
sleep 10
|
||||
- name: Doctor
|
||||
run: docker compose exec -T appwrite doctor
|
||||
|
||||
- name: Environment Variables
|
||||
run: docker compose exec -T appwrite vars
|
||||
|
||||
- name: Run Tests
|
||||
run: docker compose exec -T appwrite test --debug
|
||||
|
||||
- name: Teardown
|
||||
if: always()
|
||||
run: |
|
||||
docker ps -aq | xargs docker rm --force
|
||||
docker volume prune --force
|
||||
docker network prune --force
|
||||
@@ -2,6 +2,7 @@
|
||||
/vendor/
|
||||
/node_modules/
|
||||
/tests/resources/storage/
|
||||
/tests/resources/functions/**/code.tar.gz
|
||||
/app/sdks/*
|
||||
/.idea/
|
||||
.DS_Store
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/bin/bash bash
|
||||
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Missing tag number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]
|
||||
then
|
||||
echo "Missing version number"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test $(find "./app/db/DBIP/dbip-country-lite-2021-10.mmdb" -mmin +259200)
|
||||
then
|
||||
printf "${RED}GEO country DB has not been updated for more than 6 months. Go to https://db-ip.com/db/download/ip-to-country-lite to download a newer version${NC}\n"
|
||||
fi
|
||||
|
||||
echo 'Starting build...'
|
||||
|
||||
docker build --build-arg VERSION="$2" --tag appwrite/appwrite:"$1" .
|
||||
|
||||
echo 'Pushing build to registry...'
|
||||
|
||||
docker push appwrite/appwrite:"$1"
|
||||
@@ -1 +0,0 @@
|
||||
echo 'Nothing to deploy right now.'
|
||||
@@ -1,80 +0,0 @@
|
||||
dist: focal
|
||||
|
||||
arch:
|
||||
- amd64
|
||||
- arm64-graviton2
|
||||
|
||||
os: linux
|
||||
|
||||
vm:
|
||||
size: large
|
||||
|
||||
language: shell
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- team@appwrite.io
|
||||
|
||||
before_install:
|
||||
# Install latest Docker
|
||||
- curl -fsSL https://get.docker.com | sh
|
||||
# Enable Buildkit in Docker config
|
||||
- echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json
|
||||
- mkdir -p $HOME/.docker
|
||||
- echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
|
||||
- sudo service docker start
|
||||
# Login to increase Docker Hub ratelimit
|
||||
- >
|
||||
if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then
|
||||
echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin
|
||||
fi
|
||||
- docker --version
|
||||
# Install latest Compose
|
||||
- sudo rm /usr/local/bin/docker-compose
|
||||
- curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` > docker-compose
|
||||
- chmod +x docker-compose
|
||||
- sudo mv docker-compose /usr/local/bin
|
||||
- docker-compose --version
|
||||
# Enable Buildkit
|
||||
- docker buildx create --name travis_builder --use
|
||||
- export COMPOSE_INTERACTIVE_NO_CLI
|
||||
- export DOCKER_BUILDKIT=1
|
||||
- export COMPOSE_DOCKER_CLI_BUILD=1
|
||||
- export BUILDKIT_PROGRESS=plain
|
||||
# Only pass a single runtime for CI stability
|
||||
- echo "_APP_FUNCTIONS_RUNTIMES=php-8.0" >> .env
|
||||
# Ensure Travis scripts are executable
|
||||
- chmod -R u+x ./.travis-ci
|
||||
|
||||
install:
|
||||
- docker-compose pull
|
||||
# Upstream bug causes buildkit pulls to fail so prefetch base images
|
||||
# https://github.com/moby/moby/issues/41864
|
||||
- docker pull composer:2.0
|
||||
- docker pull php:8.0-cli-alpine
|
||||
- docker-compose build
|
||||
- docker-compose up -d
|
||||
- sleep 10
|
||||
|
||||
script:
|
||||
- docker ps
|
||||
- docker-compose logs appwrite
|
||||
- docker-compose logs appwrite-worker-functions
|
||||
- docker-compose exec appwrite doctor
|
||||
- docker-compose exec appwrite vars
|
||||
- docker-compose exec appwrite test --debug
|
||||
|
||||
after_script:
|
||||
# travis re-uses their build nodes so clean them up
|
||||
- docker buildx rm travis_builder
|
||||
|
||||
after_failure:
|
||||
- docker-compose logs appwrite
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
edge: true
|
||||
script: ./.travis-ci/deploy.sh
|
||||
on:
|
||||
repo: appwrite/appwrite
|
||||
branch: deploy
|
||||
@@ -1,3 +1,227 @@
|
||||
# Version 0.13.4
|
||||
|
||||
## Features
|
||||
- Added `detailedTrace` to Logger events
|
||||
- Added new `_APP_STORAGE_PREVIEW_LIMIT` environment variable to configure maximum preview file size
|
||||
|
||||
## Bugs
|
||||
- Fixed missing volume mount in Docker Compose
|
||||
- Fixed upload with Bucket File permission
|
||||
- Fixed custom ID validation in Console
|
||||
- Fixed file preview with no `output` passed
|
||||
- Fixed GitHub issue URL in Console
|
||||
- Fixed double PDOException logging
|
||||
- Fixed functions cleanup when container is already initialized
|
||||
- Fixed float input precision in Console
|
||||
|
||||
# Version 0.13.3
|
||||
## Bugs
|
||||
- Fixed search for terms that inlcude `@` characters
|
||||
- Fixed Bucket permissions
|
||||
- Fixed file upload error in UI
|
||||
- Fixed input field for float attributes in UI
|
||||
- Fixed `appwrite-executor` restart behavior in docker-compose.yml
|
||||
|
||||
# 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
|
||||
- Improved functions execution times by alot
|
||||
- Added a new worker to build deployments
|
||||
- Functions are now executed differently and your functions need to be adapted **Breaking Change**
|
||||
- Tags are now called Deployments **Breaking Change**
|
||||
- Renamed `tagId` to `deplyomentId` in collections **Breaking Change**
|
||||
- Updated event names from `function.tags.*` to `function.deployments.*` **Breaking Change**
|
||||
- Java runtimes are currently not supported **Breaking Change**
|
||||
### Storage
|
||||
- Added Buckets
|
||||
- Buckets allow you to configure following settings:
|
||||
- Maximum File Size
|
||||
- Enabled/Disabled
|
||||
- Encryption
|
||||
- Anti Virus
|
||||
- Allowed file extensions
|
||||
- Permissions
|
||||
- Bucket Level
|
||||
- File Level
|
||||
- Support for S3 and Digitalocean Spaces
|
||||
- Efficiently process large files by loading only chunks
|
||||
- Files larger then 5MB needs to be uploaded in chunks using Content-Range header. SDKs handle this internally **Breaking Change**
|
||||
- Encryption, Compression is now limited to files smaller or equal to 20MB
|
||||
- New UI in the console for uploading files with progress indication
|
||||
- Concurrent file uploads
|
||||
- Added `buckets.read` and `buckets.write` scope to API keys
|
||||
|
||||
### Account
|
||||
- Renamed `providerToken` to `providerAccessToken` in sessions **Breaking Change**
|
||||
- New endpoint to refresh the OAuth Access Token
|
||||
- OAuth sessions now include `providerAccessTokenExpiry` and `providerRefreshToken`
|
||||
- Notion and Stripe have been added to the OAuth Providers
|
||||
- Microsoft OAuth provider now supports custom domains
|
||||
|
||||
### Others
|
||||
- Renamed `sum` to `total` on multiple endpoints returning a list of resource **Breaking Change**
|
||||
- Added new `_APP_WORKER_PER_CORE` environment variable to configure the amount of internal workers per core for performance optimization
|
||||
|
||||
## Bugs
|
||||
- Fixed issue with 36 character long custom IDs
|
||||
- Fixed permission issues and is now more consistent and returns all resources
|
||||
- Fixed total amount of documents not being updated
|
||||
- Fixed issue with searching though memberships
|
||||
- Fixed image preview rotation
|
||||
- Fixed Database index names that contain SQL keywords
|
||||
- Fixed UI to reveal long e-mail addresses on User list
|
||||
- Fixed UI for Attribute default value field to reset after submit
|
||||
- Fixed UI to check for new available version of Appwrite
|
||||
- Fixed UI default values when creating Integer or Float attributes
|
||||
- Removed `_project` prepend from internal Database Schema
|
||||
- Added dedicated internal permissions table for each Collection
|
||||
|
||||
## Security
|
||||
- Remove `appwrite.io` and `appwrite.test` from authorized domains for session verification
|
||||
|
||||
## Upgrades
|
||||
|
||||
- Upgraded `redis` extenstion to version 5.3.7
|
||||
- Upgraded `swoole` extenstion to version 4.8.7
|
||||
- Upgraded GEO IP database to version March 2022
|
||||
|
||||
# Version 0.12.3
|
||||
|
||||
## Bugs
|
||||
- Fix update membership roles (#2799)
|
||||
- Fix migration to 0.12.x to populate search fields (#2799)
|
||||
|
||||
## Security
|
||||
- Fix URL schema Validation to only allow http/https (#2801)
|
||||
|
||||
# Version 0.12.2
|
||||
|
||||
## Bugs
|
||||
- Fix security vulnerability in the Console (#2778)
|
||||
- Fix security vulnerability in the ACME-Challenge (#2780)
|
||||
|
||||
## Upgrades
|
||||
|
||||
- Upgraded `redis` extenstion to version 5.3.6
|
||||
- Upgraded `swoole` extenstion to version 4.8.6
|
||||
- Upgraded `imagick` extenstion to version 3.7.0
|
||||
- Upgraded GEO IP database to version February 2022
|
||||
|
||||
# Version 0.12.1
|
||||
|
||||
## Bugs
|
||||
- Fixed some issues with the Migration
|
||||
- Fixed the UI to add Variables to Functions
|
||||
- Fixed wrong data type for String Attribute size
|
||||
- Fixed Request stats on the console
|
||||
- Fixed Realtime Connection stats with high number by abbreviation
|
||||
- Fixed backward compatibility of account status attribute.
|
||||
|
||||
# Version 0.12.0
|
||||
|
||||
## Features
|
||||
|
||||
- Completely rewritten Database service: **Breaking Change**
|
||||
- Collection rules are now attributes
|
||||
- Filters for have been replaced with a new, more powerful syntax
|
||||
- Custom indexes for more performant queries
|
||||
- Enum Attributes
|
||||
- Maximum `sum` returned does not exceed 5000 documents anymore **Breaking Change**
|
||||
- **DEPRECATED** Nested documents has been removed
|
||||
- **DEPRECATED** Wildcard rule has been removed
|
||||
- You can now set custom ID’s when creating following resources:
|
||||
- User
|
||||
- Team
|
||||
- Function
|
||||
- Project
|
||||
- File
|
||||
- Collection
|
||||
- Document
|
||||
- All resources with custom ID support required you to set an ID now
|
||||
- Passing `unique()` will generate a unique ID
|
||||
- Auto-generated ID's are now 20 characters long
|
||||
- Wildcard permissions `*` are now `role:all` **Breaking Change**
|
||||
- Collections can be enabled and disabled
|
||||
- Permissions are now found as top-level keys `$read` and `$write` instead of nested under `$permissions`
|
||||
- Accessing collections with insufficient permissions now return a `401` isntead of `404` status code
|
||||
- Offset cannot be higher than 5000 now and cursor pagination is required
|
||||
- Added Cursor pagination to all endpoints that provide pagination by offset
|
||||
- Added new Usage worker to aggregate usage statistics
|
||||
- Added new Database worker to handle heavy database tasks in the background
|
||||
- Added detailed Usage statistics to following services in the Console:
|
||||
- Users
|
||||
- Storage
|
||||
- Database
|
||||
- You can now disable/enable following services in the Console:
|
||||
- Account
|
||||
- Avatars
|
||||
- Database
|
||||
- Locale
|
||||
- Health
|
||||
- Storage
|
||||
- Teams
|
||||
- Users
|
||||
- Functions
|
||||
- Fixed several memory leaks in the Console
|
||||
- Added pagination to account activities in the Console
|
||||
- Added following events from User service to Webhooks and Functions:
|
||||
- `users.update.email`
|
||||
- `users.update.name`
|
||||
- `users.update.password`
|
||||
- Added new environment variables to enable error logging:
|
||||
- The `_APP_LOGGING_PROVIDER` variable allows you to enable the logger set the value to one of `sentry`, `raygun`, `appsignal`.
|
||||
- The `_APP_LOGGING_CONFIG` variable configures authentication to 3rd party error logging providers. If using Sentry, this should be 'SENTRY_API_KEY;SENTRY_APP_ID'. If using Raygun, this should be Raygun API key. If using AppSignal, this should be AppSignal API key.
|
||||
- Added new environment variable `_APP_USAGE_AGGREGATION_INTERVAL` to configure the usage worker interval
|
||||
- Added negative rotation values to file preview endpoint
|
||||
- Multiple responses from the Health service were changed to new (better) schema **Breaking Change**
|
||||
- Method `health.getAntiVirus()` has been renamed to `health.getAntivirus()`
|
||||
- Added following langauges to the Locale service:
|
||||
- Latin
|
||||
- Sindhi
|
||||
- Telugu
|
||||
- **DEPRECATED** Tasks service **Breaking Change**
|
||||
|
||||
## Bugs
|
||||
- Fixed `/v1/avatars/initials` when no space in the name, will try to split by `_`
|
||||
- Fixed all audit logs now saving all relevant informations
|
||||
- Fixed Health endpoints for `db` and `cache`
|
||||
|
||||
## Security
|
||||
- Increased minimum password length to 8 and removed maximum length
|
||||
- Limited User Preferences to 65kb total size
|
||||
- Upgraded Redis to 6.2
|
||||
- Upgraded InfluxDB to 1.4.0
|
||||
- Upgraded Telegraf to 1.3.0
|
||||
|
||||
# Version 0.11.1
|
||||
|
||||
## Bugs
|
||||
- Fix security vulnerability in the Console (#2777)
|
||||
- Fix security vulnerability in the ACME-Challenge (#2779)
|
||||
|
||||
## Upgrades
|
||||
- Upgraded redis extenstion to version 5.3.6
|
||||
- Upgraded swoole extenstion to version 4.8.6
|
||||
- Upgraded imagick extenstion to version 3.7.0
|
||||
- Upgraded yaml extenstion to version 2.2.2
|
||||
- Upgraded maxminddb extenstion to version 1.11.0
|
||||
- Upgraded GEO IP database to version February 2022
|
||||
|
||||
# Version 0.11.0
|
||||
|
||||
## Features
|
||||
@@ -9,6 +233,8 @@
|
||||
- Deno 1.12
|
||||
- Deno 1.13
|
||||
- Deno 1.14
|
||||
- PHP 8.1
|
||||
- Node 17
|
||||
- Added translations:
|
||||
- German `de` by @SoftCreatR in https://github.com/appwrite/appwrite/pull/1790
|
||||
- Hebrew `he` by @Kokoden in https://github.com/appwrite/appwrite/pull/1846
|
||||
@@ -76,7 +302,6 @@
|
||||
## Bugs
|
||||
- Fixed memory leak in realtime service (#1606)
|
||||
- Fixed function execution output now being UTF-8 encoded before saved (#1607)
|
||||
|
||||
# Version 0.10.2
|
||||
|
||||
## Bugs
|
||||
@@ -100,7 +325,7 @@
|
||||
- Refactored E-Mail template (#1422)
|
||||
- Improved locale management (#1440)
|
||||
- Added `$permissions` to execution response (#948)
|
||||
- Switch from using Docker CLI to Docker API by intergrating [utopia-php/orchestration](https://github.com/utopia-php/orchestration) (#1420)
|
||||
- Switch from using Docker CLI to Docker API by integrating [utopia-php/orchestration](https://github.com/utopia-php/orchestration) (#1420)
|
||||
- Added DOCKERHUB_PULL_USERNAME, DOCKERHUB_PULL_PASSWORD and DOCKERHUB_PULL_EMAIL env variables for pulling from private DockerHub repos (#1420)
|
||||
- Added `updateName`, `updateEmail` and `updatePassword` to Users service and console (#1547)
|
||||
|
||||
@@ -108,9 +333,7 @@
|
||||
- Fixed MariaDB timeout after 24 hours (#1510)
|
||||
- Fixed upgrading installation with customized `docker-compose.yml` file (#1513)
|
||||
- Fixed usage stats on the dashboard displaying invalid total users count (#1514)
|
||||
|
||||
# Version 0.9.4
|
||||
|
||||
## Security
|
||||
|
||||
- Fixed security vulnerability that exposes project ID's from other admin users (#1453)
|
||||
@@ -155,7 +378,7 @@
|
||||
- Added internal support for connection pools for improved performance (#1278)
|
||||
- Added new abstraction for workers executable files (#1276)
|
||||
- Added a new API in the Users API to allow you to force update your user verification status (#1223)
|
||||
- Using a fixed commit to avoid breaking changes for imagemagick extenstion (#1274)
|
||||
- Using a fixed commit to avoid breaking changes for imagemagick extension (#1274)
|
||||
- Updated the design of all the email templates (#1225)
|
||||
- Refactored Devices page in Console: (#1167)
|
||||
- Renamed *Devices* to *Sessions*
|
||||
@@ -186,7 +409,7 @@
|
||||
- Fixed a bug in the Twitch OAuth adapter (#1209)
|
||||
- Fixed missing session object when OAuth session creation event is triggered (#1208)
|
||||
- Fixed bug where we didn't ignore the email case, converted all emails to lowercase internally (#1243)
|
||||
- Fixed a console bug where you can't click a user with no name, added a placehoder for anonyomous users (#1220)
|
||||
- Fixed a console bug where you can't click a user with no name, added a placeholder for anonymous users (#1220)
|
||||
- Fixed unique keys not being updated when changing a user's email address (#1301)
|
||||
- Fixed a bug where decimal integers where wrongly used with database filters (#1349)
|
||||
|
||||
@@ -280,8 +503,8 @@
|
||||
|
||||
## Upgrades
|
||||
|
||||
- Upgraded redis extenstion lib to version 5.3.3
|
||||
- Upgraded maxmind extenstion lib to version 1.10.0
|
||||
- Upgraded redis extension lib to version 5.3.3
|
||||
- Upgraded maxmind extension lib to version 1.10.0
|
||||
- Upgraded utopia-php/cli lib to version 0.10.0
|
||||
- Upgraded matomo/device-detector lib to version 4.1.0
|
||||
- Upgraded dragonmantank/cron-expression lib to version 3.1.0
|
||||
@@ -293,7 +516,7 @@
|
||||
## Bug Fixes
|
||||
|
||||
- Updated missing storage env vars
|
||||
- Fixed a bug, that added a wrong timzone offset to user log timestamps
|
||||
- Fixed a bug, that added a wrong timezone offset to user log timestamps
|
||||
- Fixed a bug, that Response format header was not added in the access-control-allow-header list.
|
||||
- Fixed a bug where countryName is unknown on sessions (#933)
|
||||
- Added missing event users.update.prefs (#952)
|
||||
@@ -372,13 +595,13 @@
|
||||
- Upgraded Influxdb Docker image to version 1.8 (alpine)
|
||||
- Upgraded Redis Resque queue library to version 1.3.6 ([#319](https://github.com/appwrite/appwrite/issues/319))
|
||||
- Upgraded ClamAV container image to version 1.0.11 ([#412](https://github.com/appwrite/appwrite/issues/412))
|
||||
- Upgraded device detctor to version 3.12.6
|
||||
- Upgraded device detector to version 3.12.6
|
||||
- Upgraded GEOIP DB file to Feb 2021 release
|
||||
|
||||
## Breaking Changes (Read before upgrading!)
|
||||
|
||||
- **Deprecated** `first` and `last` query params for documents list route in the database API
|
||||
- **Deprecated** Deprectaed Pubjabi Translations ('pn')
|
||||
- **Deprecated** Deprecated Pubjabi Translations ('pn')
|
||||
- **Deprecated** `PATCH /account/prefs` is now updating the prefs payload and not just merging it
|
||||
- **Deprecated** `PATCH /users/:userId/prefs` is now updating the prefs payload and not just merging it
|
||||
- Switched order of limit and offset params in all the SDKs `listDocuments` method for better consistency
|
||||
@@ -424,7 +647,7 @@
|
||||
- Block iframe access to Appwrite console using the `X-Frame-Options` header.
|
||||
- Fixed `roles` param input validator
|
||||
- API Keys are now stored encrypted
|
||||
- Disabled domains whitlist ACL for the Appwrite console
|
||||
- Disabled domains whitelist ACL for the Appwrite console
|
||||
|
||||
# Version 0.6.2 (PRE-RELEASE)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ We would ❤️ for you to contribute to Appwrite and help make it better! We wa
|
||||
|
||||
## How to Start?
|
||||
|
||||
If you are worried or don’t know where to start, check out our next section explaining what kind of help we could use and where can you get involved. You can reach out with questions to [Eldad Fux (@eldadfux)](https://twitter.com/eldadfux) or [@appwrite_io](https://twitter.com/appwrite_io) on Twitter, and anyone from the [Appwrite team on Discord](https://discord.gg/GSeTUeA). You can also submit an issue, and a maintainer can guide you!
|
||||
If you are worried or don’t know where to start, check out our next section explaining what kind of help we could use and where can you get involved. You can reach out with questions to [Eldad Fux (@eldadfux)](https://twitter.com/eldadfux) or [@appwrite](https://twitter.com/appwrite) on Twitter, and anyone from the [Appwrite team on Discord](https://discord.gg/GSeTUeA). You can also submit an issue, and a maintainer can guide you!
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
@@ -48,9 +48,9 @@ $ git checkout -b [name_of_your_new_branch]
|
||||
$ git push origin [name_of_your_new_branch]
|
||||
```
|
||||
|
||||
5. Submit your changes for review
|
||||
5. Submit your changes for review
|
||||
If you go to your repository on GitHub, you'll see a `Compare & pull request` button. Click on that button.
|
||||
6. Start a Pull Request
|
||||
6. Start a Pull Request
|
||||
Now submit the pull request and click on `Create pull request`.
|
||||
7. Get a code review approval/reject
|
||||
8. After approval, merge your PR
|
||||
@@ -282,7 +282,28 @@ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||
```
|
||||
**Build Functions Runtimes**
|
||||
|
||||
The Runtimes for all supported cloud functions (multicore builds) can be found at the [appwrite/php-runtimes](https://github.com/appwrite/php-runtimes) repository.
|
||||
The Runtimes for all supported cloud functions (multicore builds) can be found at the [open-runtimes/open-runtimes](https://github.com/open-runtimes/open-runtimes) repository.
|
||||
|
||||
## Generate SDK
|
||||
|
||||
For generating a new console SDK follow the next steps:
|
||||
|
||||
1. Update the console spec file located at `app/config/specs/swagger2-0.12.x.console.json` from the dynamic version located at `https://localhost/specs/swagger2?platform=console`
|
||||
2. Generate a new SDK using the command `php app/cli.php sdks`
|
||||
3. Change your working dir using `cd app/sdks/console-web`
|
||||
4. Build the new SDK `npm run build`
|
||||
5. Copy `iife/sdk.js` to `appwrite.js`
|
||||
6. Go back to the root of the project `run npm run build`
|
||||
|
||||
## Checklist for Releasing SDKs
|
||||
|
||||
Things to remember when releasing SDKs
|
||||
|
||||
* Update the Changelogs in **docs/sdks** (right now only Dart and Flutter are using these)
|
||||
* Update **GETTING_STARTED.md** in **docs/sdks** for each SDKs if any changes in the related APIs in there
|
||||
* Update SDK versions as required on **app/config/platforms.php**
|
||||
* Generate SDKs using the command `php app/cli.php sdks` and follow the instructions
|
||||
* Release new tags on GitHub repository for each SDKs
|
||||
|
||||
## Debug
|
||||
|
||||
@@ -395,7 +416,7 @@ Pull requests are great, but there are many other areas where you can help Appwr
|
||||
|
||||
### Blogging & Speaking
|
||||
|
||||
Blogging, speaking about, or creating tutorials about one of Appwrite’s many features. Mention [@appwrite_io](https://twitter.com/appwrite_io) on Twitter and/or [email team@appwrite.io](mailto:team@appwrite.io) so we can give pointers and tips and help you spread the word by promoting your content on the different Appwrite communication channels. Please add your blog posts and videos of talks to our [Awesome Appwrite](https://github.com/appwrite/awesome-appwrite) repo on GitHub.
|
||||
Blogging, speaking about, or creating tutorials about one of Appwrite’s many features. Mention [@appwrite](https://twitter.com/appwrite) on Twitter and/or [email team@appwrite.io](mailto:team@appwrite.io) so we can give pointers and tips and help you spread the word by promoting your content on the different Appwrite communication channels. Please add your blog posts and videos of talks to our [Awesome Appwrite](https://github.com/appwrite/awesome-appwrite) repo on GitHub.
|
||||
|
||||
### Presenting at Meetups
|
||||
|
||||
|
||||
@@ -8,20 +8,33 @@ WORKDIR /usr/local/src/
|
||||
COPY composer.lock /usr/local/src/
|
||||
COPY composer.json /usr/local/src/
|
||||
|
||||
RUN composer update --ignore-platform-reqs --optimize-autoloader \
|
||||
RUN composer install --ignore-platform-reqs --optimize-autoloader \
|
||||
--no-plugins --no-scripts --prefer-dist \
|
||||
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
|
||||
|
||||
FROM php:8.0-cli-alpine as compile
|
||||
FROM node:16.13.2-alpine3.15 as node
|
||||
|
||||
WORKDIR /usr/local/src/
|
||||
|
||||
COPY package-lock.json /usr/local/src/
|
||||
COPY package.json /usr/local/src/
|
||||
COPY gulpfile.js /usr/local/src/
|
||||
COPY public /usr/local/src/public
|
||||
|
||||
RUN npm ci
|
||||
RUN npm run build
|
||||
|
||||
FROM php:8.0.14-cli-alpine3.15 as compile
|
||||
|
||||
ARG DEBUG=false
|
||||
ENV DEBUG=$DEBUG
|
||||
|
||||
ENV PHP_REDIS_VERSION=5.3.4 \
|
||||
PHP_SWOOLE_VERSION=v4.8.0 \
|
||||
PHP_IMAGICK_VERSION=3.5.1 \
|
||||
PHP_YAML_VERSION=2.2.1 \
|
||||
PHP_MAXMINDDB_VERSION=v1.10.1
|
||||
ENV PHP_REDIS_VERSION=5.3.7 \
|
||||
PHP_MONGODB_VERSION=1.9.1 \
|
||||
PHP_SWOOLE_VERSION=v4.8.7 \
|
||||
PHP_IMAGICK_VERSION=3.7.0 \
|
||||
PHP_YAML_VERSION=2.2.2 \
|
||||
PHP_MAXMINDDB_VERSION=v1.11.0
|
||||
|
||||
RUN \
|
||||
apk add --no-cache --virtual .deps \
|
||||
@@ -100,7 +113,17 @@ RUN \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
FROM php:8.0-cli-alpine as final
|
||||
# Mongodb Extension
|
||||
FROM compile as mongodb
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_MONGODB_VERSION https://github.com/mongodb/mongo-php-driver.git && \
|
||||
cd mongo-php-driver && \
|
||||
git submodule update --init && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
FROM php:8.0.14-cli-alpine3.15 as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
|
||||
@@ -111,6 +134,7 @@ ENV DEBUG=$DEBUG
|
||||
ENV _APP_SERVER=swoole \
|
||||
_APP_ENV=production \
|
||||
_APP_LOCALE=en \
|
||||
_APP_WORKER_PER_CORE= \
|
||||
_APP_DOMAIN=localhost \
|
||||
_APP_DOMAIN_TARGET=localhost \
|
||||
_APP_HOME=https://appwrite.io \
|
||||
@@ -129,6 +153,15 @@ ENV _APP_SERVER=swoole \
|
||||
_APP_STORAGE_ANTIVIRUS=enabled \
|
||||
_APP_STORAGE_ANTIVIRUS_HOST=clamav \
|
||||
_APP_STORAGE_ANTIVIRUS_PORT=3310 \
|
||||
_APP_STORAGE_DEVICE=Local \
|
||||
_APP_STORAGE_S3_ACCESS_KEY= \
|
||||
_APP_STORAGE_S3_SECRET= \
|
||||
_APP_STORAGE_S3_REGION= \
|
||||
_APP_STORAGE_S3_BUCKET= \
|
||||
_APP_STORAGE_DO_SPACES_ACCESS_KEY= \
|
||||
_APP_STORAGE_DO_SPACES_SECRET= \
|
||||
_APP_STORAGE_DO_SPACES_REGION= \
|
||||
_APP_STORAGE_DO_SPACES_BUCKET= \
|
||||
_APP_REDIS_HOST=redis \
|
||||
_APP_REDIS_PORT=6379 \
|
||||
_APP_DB_HOST=mariadb \
|
||||
@@ -145,11 +178,14 @@ ENV _APP_SERVER=swoole \
|
||||
_APP_SMTP_SECURE= \
|
||||
_APP_SMTP_USERNAME= \
|
||||
_APP_SMTP_PASSWORD= \
|
||||
_APP_FUNCTIONS_SIZE_LIMIT=30000000 \
|
||||
_APP_FUNCTIONS_TIMEOUT=900 \
|
||||
_APP_FUNCTIONS_CONTAINERS=10 \
|
||||
_APP_FUNCTIONS_CPUS=1 \
|
||||
_APP_FUNCTIONS_MEMORY=128 \
|
||||
_APP_FUNCTIONS_MEMORY_SWAP=128 \
|
||||
_APP_EXECUTOR_SECRET=a-random-secret \
|
||||
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes \
|
||||
_APP_SETUP=self-hosted \
|
||||
_APP_VERSION=$VERSION \
|
||||
_APP_USAGE_STATS=enabled \
|
||||
@@ -158,7 +194,9 @@ ENV _APP_SERVER=swoole \
|
||||
_APP_MAINTENANCE_RETENTION_AUDIT=1209600 \
|
||||
# 1 Day = 86400 s
|
||||
_APP_MAINTENANCE_RETENTION_ABUSE=86400 \
|
||||
_APP_MAINTENANCE_INTERVAL=86400
|
||||
_APP_MAINTENANCE_INTERVAL=86400 \
|
||||
_APP_LOGGING_PROVIDER= \
|
||||
_APP_LOGGING_CONFIG=
|
||||
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
@@ -195,17 +233,20 @@ RUN \
|
||||
WORKDIR /usr/src/code
|
||||
|
||||
COPY --from=composer /usr/local/src/vendor /usr/src/code/vendor
|
||||
COPY --from=node /usr/local/src/public/dist /usr/src/code/public/dist
|
||||
COPY --from=swoole /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yasd.so* /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=redis /usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=imagick /usr/local/lib/php/extensions/no-debug-non-zts-20200930/imagick.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=yaml /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=maxmind /usr/local/lib/php/extensions/no-debug-non-zts-20200930/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=mongodb /usr/local/lib/php/extensions/no-debug-non-zts-20200930/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
|
||||
# Add Source Code
|
||||
COPY ./app /usr/src/code/app
|
||||
COPY ./bin /usr/local/bin
|
||||
COPY ./docs /usr/src/code/docs
|
||||
COPY ./public /usr/src/code/public
|
||||
COPY ./public/fonts /usr/src/code/public/fonts
|
||||
COPY ./public/images /usr/src/code/public/images
|
||||
COPY ./src /usr/src/code/src
|
||||
|
||||
# Set Volumes
|
||||
@@ -225,21 +266,24 @@ RUN mkdir -p /storage/uploads && \
|
||||
# Executables
|
||||
RUN chmod +x /usr/local/bin/doctor && \
|
||||
chmod +x /usr/local/bin/maintenance && \
|
||||
chmod +x /usr/local/bin/usage && \
|
||||
chmod +x /usr/local/bin/install && \
|
||||
chmod +x /usr/local/bin/migrate && \
|
||||
chmod +x /usr/local/bin/realtime && \
|
||||
chmod +x /usr/local/bin/executor && \
|
||||
chmod +x /usr/local/bin/schedule && \
|
||||
chmod +x /usr/local/bin/sdks && \
|
||||
chmod +x /usr/local/bin/specs && \
|
||||
chmod +x /usr/local/bin/ssl && \
|
||||
chmod +x /usr/local/bin/test && \
|
||||
chmod +x /usr/local/bin/vars && \
|
||||
chmod +x /usr/local/bin/worker-audits && \
|
||||
chmod +x /usr/local/bin/worker-certificates && \
|
||||
chmod +x /usr/local/bin/worker-database && \
|
||||
chmod +x /usr/local/bin/worker-deletes && \
|
||||
chmod +x /usr/local/bin/worker-functions && \
|
||||
chmod +x /usr/local/bin/worker-builds && \
|
||||
chmod +x /usr/local/bin/worker-mails && \
|
||||
chmod +x /usr/local/bin/worker-tasks && \
|
||||
chmod +x /usr/local/bin/worker-usage && \
|
||||
chmod +x /usr/local/bin/worker-webhooks
|
||||
|
||||
# Letsencrypt Permissions
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
<br />
|
||||
<p align="center">
|
||||
<a href="https://appwrite.io" target="_blank"><img width="260" height="39" src="https://appwrite.io/images/appwrite.svg" alt="Appwrite Logo"></a>
|
||||
<br />
|
||||
<br />
|
||||
<b>适用于[Flutter/Vue/Angular/React/iOS/Android/* 等等平台 *]的完整后端服务</b>
|
||||
<br />
|
||||
<br />
|
||||
</p>
|
||||
|
||||
<!-- [](https://hacktoberfest.appwrite.io) -->
|
||||
[](https://appwrite.io/discord?r=Github)
|
||||
[](https://hub.docker.com/r/appwrite/appwrite)
|
||||
[](https://travis-ci.com/appwrite/appwrite)
|
||||
[](https://twitter.com/appwrite)
|
||||
[](docs/tutorials/add-translations.md)
|
||||
[](https://store.appwrite.io)
|
||||
|
||||
[English](README.md) | 简体中文
|
||||
|
||||
Appwrite是一个基于Docker的端到端开发者平台,其容器化的微服务库可应用于网页端,移动端,以及后端。Appwrite 通过视觉化界面极简了从零编写 API 的繁琐过程,在保证软件安全的前提下为开发者创造了一个高效的开发环境。
|
||||
|
||||
Appwrite 可以提供给开发者用户验证,外部授权,用户数据读写检索,文件储存, 图像处理,云函数计算,[等多种服务](https://appwrite.io/docs).
|
||||
|
||||

|
||||
|
||||
更多信息请到 Appwrite 官网查看: [https://appwrite.io](https://appwrite.io)
|
||||
|
||||
内容:
|
||||
|
||||
- [安装](#安装)
|
||||
- [Unix](#unix)
|
||||
- [Windows](#windows)
|
||||
- [CMD](#cmd)
|
||||
- [PowerShell](#powershell)
|
||||
- [从旧版本升级](#从旧版本升级)
|
||||
- [入门](#入门)
|
||||
- [软件服务](#软件服务)
|
||||
- [开发套件](#开发套件)
|
||||
- [客户端](#客户端)
|
||||
- [服务器](#服务器)
|
||||
- [开发者社区](#开发者社区)
|
||||
- [软件架构](#软件架构)
|
||||
- [贡献代码](#贡献代码)
|
||||
- [安全](#安全)
|
||||
- [订阅我们](#订阅我们)
|
||||
- [版权说明](#版权说明)
|
||||
|
||||
## 安装
|
||||
|
||||
Appwrite 的容器化服务器只需要一行指令就可以运行。您可以使用 docker-compose 在本地主机上运行 Appwrite,也可以在任何其他容器化工具(如 Kubernetes、Docker Swarm 或 Rancher)上运行 Appwrite。
|
||||
|
||||
开始运行 Appwrite 服务器的最简单方法是运行我们的 docker-compose 文件。在运行安装命令之前,请确保您的机器上安装了 [Docker](https://dockerdocs.cn/get-docker/index.html):
|
||||
|
||||
### Unix
|
||||
|
||||
```bash
|
||||
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.4
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
||||
#### CMD
|
||||
|
||||
```cmd
|
||||
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.4
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
||||
```powershell
|
||||
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.4
|
||||
```
|
||||
|
||||
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。
|
||||
|
||||
|
||||
需要自定义容器构架,请查看我们的 Docker [环境变量](https://appwrite.io/docs/environment-variables) 文档。您还可以参考我们的 [docker-compose.yml](https://gist.github.com/eldadfux/977869ff6bdd7312adfd4e629ee15cc5#file-docker-compose-yml) 文件手动设置环境。
|
||||
|
||||
### 从旧版本升级
|
||||
|
||||
如果您从旧版本升级 Appwrite 服务器,则应在设置完成后使用 Appwrite 迁移工具。有关这方面的更多信息,请查看 [安装文档](https://appwrite.io/docs/installation)。
|
||||
|
||||
## 入门
|
||||
|
||||
开始使用 Appwrite 只需要在控制台创建一个新项目,选择开发平台,然后抓取我们的开发套件。您可以从以下的教程中找到你喜欢的平台开始使用 Appwrite。
|
||||
|
||||
* [开始使用 Web](https://appwrite.io/docs/getting-started-for-web)
|
||||
* [开始使用 Flutter](https://appwrite.io/docs/getting-started-for-flutter)
|
||||
* [开始使用 Apple](https://appwrite.io/docs/getting-started-for-apple)
|
||||
* [开始使用 Android](https://appwrite.io/docs/getting-started-for-android)
|
||||
* [开始使用 Server](https://appwrite.io/docs/getting-started-for-server)
|
||||
* [开始使用 CLI](https://appwrite.io/docs/command-line)
|
||||
|
||||
### 软件服务
|
||||
|
||||
* [**帐户**](https://appwrite.io/docs/client/account) -管理当前用户的帐户和登录方式。跟踪和管理用户 Session,登录设备,登录方法和查看相关记录。
|
||||
* [**用户**](https://appwrite.io/docs/server/users) - 在以管理员模式登录时管理和列出所有用户。
|
||||
* [**团队**](https://appwrite.io/docs/client/teams) - 管理用户分组。邀请成员,管理团队中的用户权限和用户角色。
|
||||
* [**数据库**](https://appwrite.io/docs/client/database) - 管理数据库文档和文档集。用检索界面来对文档和文档集进行读取,创建,更新,和删除。
|
||||
* [**贮存**](https://appwrite.io/docs/client/storage) - 管理文件的阅读、创建、删除和预览。设置文件的预览来满足程序的个性化需求。所有文件都由 ClamAV 扫描并安全存储和加密。
|
||||
* [**云函数**](https://appwrite.io/docs/server/functions) - 在安全,隔离的环境中运行自定义代码。这些代码可以被事件,CRON,或者手动操作触发。
|
||||
* [**语言适配**](https://appwrite.io/docs/client/locale) - 根据用户所在的的国家和地区做出合适的语言适配。
|
||||
* [**头像**](https://appwrite.io/docs/client/avatars) -管理用户头像、国家旗帜、浏览器图标、信用卡符号,和生成二维码。
|
||||
如需完整的 API 界面文档,请访问 [https://appwrite.io/docs](https://appwrite.io/docs)。如需更多教程、新闻和公告,请订阅我们的 [博客](https://medium.com/appwrite-io) 和 加入我们的[Discord 社区](https://discord.gg/GSeTUeA)。
|
||||
|
||||
### 开发套件
|
||||
|
||||
以下是当前支持的平台和语言列表。如果您想帮助我们为您选择的平台添加支持,您可以访问我们的 [SDK 生成器](https://github.com/appwrite/sdk-generator) 项目并查看我们的 [贡献指南](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md)。
|
||||
|
||||
#### 客户端
|
||||
* ✅ [Web](https://github.com/appwrite/sdk-for-web) (由 Appwrite 团队维护)
|
||||
* ✅ [Flutter](https://github.com/appwrite/sdk-for-flutter) (由 Appwrite 团队维护)
|
||||
* ✅ [Apple](https://github.com/appwrite/sdk-for-apple) - **公测** (由 Appwrite 团队维护)
|
||||
* ✅ [Android](https://github.com/appwrite/sdk-for-android) (由 Appwrite 团队维护)
|
||||
|
||||
#### 服务器
|
||||
* ✅ [NodeJS](https://github.com/appwrite/sdk-for-node) (由 Appwrite 团队维护)
|
||||
* ✅ [PHP](https://github.com/appwrite/sdk-for-php) (由 Appwr实验 团队维护)
|
||||
* ✅ [Dart](https://github.com/appwrite/sdk-for-dart) - (由 Appwrite 团队维护)
|
||||
* ✅ [Deno](https://github.com/appwrite/sdk-for-deno) - **公测** (由 Appwrite 团队维护)
|
||||
* ✅ [Ruby](https://github.com/appwrite/sdk-for-ruby) (由 Appwrite 团队维护)
|
||||
* ✅ [Python](https://github.com/appwrite/sdk-for-python) (由 Appwrite 团队维护)
|
||||
* ✅ [Kotlin](https://github.com/appwrite/sdk-for-kotlin) - **公测** (由 Appwrite 团队维护)
|
||||
* ✅ [Apple](https://github.com/appwrite/sdk-for-apple) - **公测** (由 Appwrite 团队维护)
|
||||
* ✅ [.NET](https://github.com/appwrite/sdk-for-dotnet) - **公测** (由 Appwrite 团队维护)
|
||||
|
||||
#### 开发者社区
|
||||
* ✅ [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (维护者 [Michael Gangolf](https://github.com/m1ga/))
|
||||
* ✅ [Godot Engine](https://github.com/GodotNuts/appwrite-sdk) (维护者 [fenix-hub @GodotNuts](https://github.com/fenix-hub))
|
||||
|
||||
找不到需要的的 SDK? - 欢迎通过发起PR来帮助我们完善Appwrite的软件生态环境 [SDK 生成器](https://github.com/appwrite/sdk-generator)!
|
||||
|
||||
|
||||
## 软件架构
|
||||
|
||||

|
||||
|
||||
Appwrite 使用高拓展性的微服务架构。此外,Appwrite 支持多种 API(REST、WebSocket 和 即将推出的 GraphQL),来迎合您的个性化开发习惯。
|
||||
|
||||
Appwrite API 界面层利用后台缓存和任务委派来提供极速的响应时间。后台的 Worker 代理还允许您使用消息队列来处理负载,并精确控制硬件合理分配和成本。您可以在 [贡献指南](CONTRIBUTING.md#architecture-1) 中了解有关我们架构的更多信息。
|
||||
|
||||
## 贡献代码
|
||||
|
||||
所有代码贡献 - 包括来自具有直接提交更改权限的贡献者 - 都必须提交PR请求并在合并分支之前得到核心开发人员的批准。这是为了确保正确审查所有代码。
|
||||
|
||||
我们欢迎所有人提交PR!如果您愿意提供帮助,可以在 [贡献指南](CONTRIBUTING.md) 中了解有关如何为项目做出贡献的更多信息。
|
||||
|
||||
## 安全
|
||||
|
||||
为了保护您的隐私,请避免在GitHub 上发布安全问题。发送问题至 security@appwrite.io,我们将为您做更细致的解答。
|
||||
|
||||
## 订阅我们
|
||||
|
||||
加入我们在世界各地不断发展的社区!请参阅我们的官方 [博客](https://medium.com/appwrite-io)。在 [Twitter](https://twitter.com/appwrite)、[Facebook 页面](https://www.facebook.com/appwrite.io)、[Facebook 群组](https://www.facebook)、[开发者社区](https://dev.to/appwrite) 等平台订阅我们或加入我们的 [Discord 社区](https://discord.gg/GSeTUeA) 以获得更多帮助,想法和讨论。
|
||||
|
||||
## 版权说明
|
||||
|
||||
版权详情,访问 [BSD 3-Clause License](./LICENSE)。
|
||||
@@ -8,15 +8,18 @@
|
||||
<br />
|
||||
</p>
|
||||
|
||||
[](https://hacktoberfest.appwrite.io)
|
||||
[](https://appwrite.io/discord)
|
||||
<!-- [](https://hacktoberfest.appwrite.io) -->
|
||||
<!-- [](https://travis-ci.com/appwrite/appwrite) -->
|
||||
[](https://appwrite.io/discord?r=Github)
|
||||
[](https://hub.docker.com/r/appwrite/appwrite)
|
||||
[](https://travis-ci.com/appwrite/appwrite)
|
||||
[](https://twitter.com/appwrite_io)
|
||||
[](https://github.com/appwrite/appwrite/actions)
|
||||
[](https://twitter.com/appwrite)
|
||||
[](docs/tutorials/add-translations.md)
|
||||
<!-- [](https://store.appwrite.io) -->
|
||||
[](https://store.appwrite.io)
|
||||
|
||||
[**Appwrite 0.11 has been released! Learn what's new!**](https://dev.to/appwrite/building-apps-just-got-swifter-announcing-appwrite-v011-4g62)
|
||||
English | [简体中文](README-CN.md)
|
||||
|
||||
[**Appwrite 0.13 has been released! Learn what's new!**](https://dev.to/appwrite/announcing-appwrite-013-with-major-upgrades-to-storage-and-functions-3hpf)
|
||||
|
||||
Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker<nobr> microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.
|
||||
|
||||
@@ -40,16 +43,17 @@ Table of Contents:
|
||||
- [Client](#client)
|
||||
- [Server](#server)
|
||||
- [Community](#community)
|
||||
- [Architecture](#architecture)
|
||||
- [Contributing](#contributing)
|
||||
- [Security](#security)
|
||||
- [Follow Us](#follow-us)
|
||||
- [License](#license)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
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
|
||||
|
||||
@@ -58,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.11.0
|
||||
appwrite/appwrite:0.13.4
|
||||
```
|
||||
|
||||
### Windows
|
||||
@@ -70,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.11.0
|
||||
appwrite/appwrite:0.13.4
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
@@ -80,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.11.0
|
||||
appwrite/appwrite:0.13.4
|
||||
```
|
||||
|
||||
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.
|
||||
@@ -102,7 +106,6 @@ Getting started with Appwrite is as easy as creating a new project, choosing you
|
||||
* [Getting Started for Android](https://appwrite.io/docs/getting-started-for-android)
|
||||
* [Getting Started for Server](https://appwrite.io/docs/getting-started-for-server)
|
||||
* [Getting Started for CLI](https://appwrite.io/docs/command-line)
|
||||
* Getting Started for iOS (Coming soon...)
|
||||
|
||||
### Services
|
||||
|
||||
@@ -139,11 +142,20 @@ Below is a list of currently supported platforms and languages. If you wish to h
|
||||
* ✅ [.NET](https://github.com/appwrite/sdk-for-dotnet) - **Experimental** (Maintained by the Appwrite Team)
|
||||
|
||||
#### Community
|
||||
* ✅ [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (Maintained by [Michael Gangolf](https://github.com/m1ga/))
|
||||
* ✅ [Godot Engine](https://github.com/m1ga/ti.appwrite) (Maintained by [fenix-hub @GodotNuts](https://github.com/GodotNuts/appwrite-sdk/))
|
||||
* ✅ [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (Maintained by [Michael Gangolf](https://github.com/m1ga/))
|
||||
* ✅ [Godot Engine](https://github.com/GodotNuts/appwrite-sdk) (Maintained by [fenix-hub @GodotNuts](https://github.com/fenix-hub))
|
||||
|
||||
Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)!
|
||||
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
Appwrite uses a microservices architecture that was designed for easy scaling and delegation of responsibilities. In addition, Appwrite supports multiple APIs (REST, WebSocket, and GraphQL-soon) to allow you to interact with your resources leveraging your existing knowledge and protocols of choice.
|
||||
|
||||
The Appwrite API layer was designed to be extremely fast by leveraging in-memory caching and delegating any heavy-lifting tasks to the Appwrite background workers. The background workers also allow you to precisely control your compute capacity and costs using a message queue to handle the load. You can learn more about our architecture in the [contribution guide](CONTRIBUTING.md#architecture-1).
|
||||
|
||||
## Contributing
|
||||
|
||||
All code contributions - including those of people having commit access - must go through a pull request and be approved by a core developer before being merged. This is to ensure a proper review of all the code.
|
||||
@@ -156,7 +168,7 @@ For security issues, kindly email us at [security@appwrite.io](mailto:security@a
|
||||
|
||||
## Follow Us
|
||||
|
||||
Join our growing community around the world! See our official [Blog](https://medium.com/appwrite-io). Follow us on [Twitter](https://twitter.com/appwrite_io), [Facebook Page](https://www.facebook.com/appwrite.io), [Facebook Group](https://www.facebook.com/groups/appwrite.developers/) , [Dev Community](https://dev.to/appwrite) or join our live [Discord server](https://discord.gg/GSeTUeA) for more help, ideas, and discussions.
|
||||
Join our growing community around the world! See our official [Blog](https://medium.com/appwrite-io). Follow us on [Twitter](https://twitter.com/appwrite), [Facebook Page](https://www.facebook.com/appwrite.io), [Facebook Group](https://www.facebook.com/groups/appwrite.developers/) , [Dev Community](https://dev.to/appwrite) or join our live [Discord server](https://discord.gg/GSeTUeA) for more help, ideas, and discussions.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| < 0.5 | :x: |
|
||||
| 0.6.x | :white_check_mark: |
|
||||
| 0.7.x | :white_check_mark: |
|
||||
| 0.8.0 | :white_check_mark: |
|
||||
| <= 0.10 | :x: |
|
||||
| 0.11.x | :white_check_mark: |
|
||||
| 0.12.x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
For security issues, kindly email us at security@appwrite.io instead of posting a public issue in GitHub.
|
||||
For security issues, kindly email us at security@appwrite.io instead of posting a public issue in GitHub.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/workers.php';
|
||||
require_once __DIR__.'/init.php';
|
||||
require_once __DIR__.'/controllers/general.php';
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\CLI;
|
||||
@@ -13,8 +13,10 @@ include 'tasks/maintenance.php';
|
||||
include 'tasks/install.php';
|
||||
include 'tasks/migrate.php';
|
||||
include 'tasks/sdks.php';
|
||||
include 'tasks/specs.php';
|
||||
include 'tasks/ssl.php';
|
||||
include 'tasks/vars.php';
|
||||
include 'tasks/usage.php';
|
||||
|
||||
$cli
|
||||
->task('version')
|
||||
|
||||
@@ -5,42 +5,42 @@
|
||||
return [
|
||||
'email-password' => [
|
||||
'name' => 'Email/Password',
|
||||
'key' => 'usersAuthEmailPassword',
|
||||
'key' => 'emailPassword',
|
||||
'icon' => '/images/users/email.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateSession',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web-default#accountCreateSession',
|
||||
'enabled' => true,
|
||||
],
|
||||
'magic-url' => [
|
||||
'name' => 'Magic URL',
|
||||
'key' => 'usersAuthMagicURL',
|
||||
'icon' => '/images/users/magic-url.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateMagicURLSession',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web-default#accountCreateMagicURLSession',
|
||||
'enabled' => true,
|
||||
],
|
||||
'anonymous' => [
|
||||
'name' => 'Anonymous',
|
||||
'key' => 'usersAuthAnonymous',
|
||||
'key' => 'anonymous',
|
||||
'icon' => '/images/users/anonymous.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateAnonymousSession',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web-default#accountCreateAnonymousSession',
|
||||
'enabled' => true,
|
||||
],
|
||||
'invites' => [
|
||||
'name' => 'Invites',
|
||||
'key' => 'usersAuthInvites',
|
||||
'key' => 'invites',
|
||||
'icon' => '/images/users/invites.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/teams?sdk=web#teamsCreateMembership',
|
||||
'docs' => 'https://appwrite.io/docs/client/teams?sdk=web-default#teamsCreateMembership',
|
||||
'enabled' => true,
|
||||
],
|
||||
'jwt' => [
|
||||
'name' => 'JWT',
|
||||
'key' => 'usersAuthJWT',
|
||||
'key' => 'JWT',
|
||||
'icon' => '/images/users/jwt.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateJWT',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web-default#accountCreateJWT',
|
||||
'enabled' => true,
|
||||
],
|
||||
'phone' => [
|
||||
'name' => 'Phone',
|
||||
'key' => 'usersAuthPhone',
|
||||
'key' => 'phone',
|
||||
'icon' => '/images/users/phone.png',
|
||||
'docs' => '',
|
||||
'enabled' => false,
|
||||
|
||||
@@ -0,0 +1,495 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* List of server wide error codes and their respective messages.
|
||||
*/
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
|
||||
return [
|
||||
/** General Errors */
|
||||
Exception::GENERAL_UNKNOWN => [
|
||||
'name' => Exception::GENERAL_UNKNOWN,
|
||||
'description' => 'An unknown error has occured. Please check the logs for more information.',
|
||||
'code' => 500,
|
||||
],
|
||||
Exception::GENERAL_MOCK => [
|
||||
'name' => Exception::GENERAL_MOCK,
|
||||
'description' => 'General errors thrown by the mock controller used for testing.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::GENERAL_ACCESS_FORBIDDEN => [
|
||||
'name' => Exception::GENERAL_ACCESS_FORBIDDEN,
|
||||
'description' => 'Access to this API is forbidden.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::GENERAL_UNKNOWN_ORIGIN => [
|
||||
'name' => Exception::GENERAL_UNKNOWN_ORIGIN,
|
||||
'description' => 'The request originated from an unknown origin. If you trust this domain, please list it as a trusted platform in the Appwrite console.',
|
||||
'code' => 403,
|
||||
],
|
||||
Exception::GENERAL_SERVICE_DISABLED => [
|
||||
'name' => Exception::GENERAL_SERVICE_DISABLED,
|
||||
'description' => 'The requested service is disabled. You can enable the service from the Appwrite console.',
|
||||
'code' => 503,
|
||||
],
|
||||
Exception::GENERAL_UNAUTHORIZED_SCOPE => [
|
||||
'name' => Exception::GENERAL_UNAUTHORIZED_SCOPE,
|
||||
'description' => 'The current user or API key does not have the required scopes to access the requested resource.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::GENERAL_RATE_LIMIT_EXCEEDED => [
|
||||
'name' => Exception::GENERAL_RATE_LIMIT_EXCEEDED,
|
||||
'description' => 'Rate limit for the current endpoint has been exceeded. Please try again after some time.',
|
||||
'code' => 429,
|
||||
],
|
||||
Exception::GENERAL_SMTP_DISABLED => [
|
||||
'name' => Exception::GENERAL_SMTP_DISABLED,
|
||||
'description' => 'SMTP is disabled on your Appwrite instance. You can <a href="/docs/email-delivery">learn more about setting up SMTP</a> in our docs.',
|
||||
'code' => 503,
|
||||
],
|
||||
Exception::GENERAL_ARGUMENT_INVALID => [
|
||||
'name' => Exception::GENERAL_ARGUMENT_INVALID,
|
||||
'description' => 'The request contains one or more invalid arguments. Please refer to the endpoint documentation.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::GENERAL_QUERY_LIMIT_EXCEEDED => [
|
||||
'name' => Exception::GENERAL_QUERY_LIMIT_EXCEEDED,
|
||||
'description' => 'Query limit exceeded for the current attribute. Usage of more than 100 query values on a single attribute is prohibited.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::GENERAL_QUERY_INVALID => [
|
||||
'name' => Exception::GENERAL_QUERY_INVALID,
|
||||
'description' => 'The query\'s syntax is invalid. Please check the query and try again.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::GENERAL_ROUTE_NOT_FOUND => [
|
||||
'name' => Exception::GENERAL_ROUTE_NOT_FOUND,
|
||||
'description' => 'The requested route was not found. Please refer to the docs and try again.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::GENERAL_CURSOR_NOT_FOUND => [
|
||||
'name' => Exception::GENERAL_CURSOR_NOT_FOUND,
|
||||
'description' => 'The cursor is invalid. This can happen if the item represented by the cursor has been deleted.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::GENERAL_SERVER_ERROR => [
|
||||
'name' => Exception::GENERAL_SERVER_ERROR,
|
||||
'description' => 'An internal server error occurred.',
|
||||
'code' => 500,
|
||||
],
|
||||
|
||||
/** User Errors */
|
||||
Exception::USER_COUNT_EXCEEDED => [
|
||||
'name' => Exception::USER_COUNT_EXCEEDED,
|
||||
'description' => 'The current project has exceeded the maximum number of users. Please check your user limit in the Appwrite console.',
|
||||
'code' => 501,
|
||||
],
|
||||
Exception::USER_JWT_INVALID => [
|
||||
'name' => Exception::USER_JWT_INVALID,
|
||||
'description' => 'The JWT token is invalid. Please check the value of the X-Appwrite-JWT header to ensure the correct token is being used.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_ALREADY_EXISTS => [
|
||||
'name' => Exception::USER_ALREADY_EXISTS,
|
||||
'description' => 'A user with the same email ID already exists in your project.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::USER_BLOCKED => [
|
||||
'name' => Exception::USER_BLOCKED,
|
||||
'description' => 'The current user has been blocked. You can unblock the user from the Appwrite console.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_INVALID_TOKEN => [
|
||||
'name' => Exception::USER_INVALID_TOKEN,
|
||||
'description' => 'Invalid token passed in the request.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_PASSWORD_RESET_REQUIRED => [
|
||||
'name' => Exception::USER_PASSWORD_RESET_REQUIRED,
|
||||
'description' => 'The current user requires a password reset.',
|
||||
'code' => 412,
|
||||
],
|
||||
Exception::USER_EMAIL_NOT_WHITELISTED => [
|
||||
'name' => Exception::USER_EMAIL_NOT_WHITELISTED,
|
||||
'description' => 'The user\'s email is not part of the whitelist. Please check the _APP_CONSOLE_WHITELIST_EMAILS environment variable of your Appwrite server.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_IP_NOT_WHITELISTED => [
|
||||
'name' => Exception::USER_IP_NOT_WHITELISTED,
|
||||
'description' => 'The user\'s IP address is not part of the whitelist. Please check the _APP_CONSOLE_WHITELIST_IPS environment variable of your Appwrite server.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_INVALID_CREDENTIALS => [
|
||||
'name' => Exception::USER_INVALID_CREDENTIALS,
|
||||
'description' => 'Invalid credentials. Please check the email and password.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_ANONYMOUS_CONSOLE_PROHIBITED => [
|
||||
'name' => Exception::USER_ANONYMOUS_CONSOLE_PROHIBITED,
|
||||
'description' => 'Anonymous users cannot be created for the console project.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_SESSION_ALREADY_EXISTS => [
|
||||
'name' => Exception::USER_SESSION_ALREADY_EXISTS,
|
||||
'description' => 'Creation of anonymous users is prohibited when a session is active.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_NOT_FOUND => [
|
||||
'name' => Exception::USER_NOT_FOUND,
|
||||
'description' => 'User with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::USER_EMAIL_ALREADY_EXISTS => [
|
||||
'name' => Exception::USER_EMAIL_ALREADY_EXISTS,
|
||||
'description' => 'Another user with the same email already exists in the current project.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::USER_PASSWORD_MISMATCH => [
|
||||
'name' => Exception::USER_PASSWORD_MISMATCH,
|
||||
'description' => 'Passwords do not match. Please check the password and confirm password.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::USER_SESSION_NOT_FOUND => [
|
||||
'name' => Exception::USER_SESSION_NOT_FOUND,
|
||||
'description' => 'The current user session could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::USER_UNAUTHORIZED => [
|
||||
'name' => Exception::USER_UNAUTHORIZED,
|
||||
'description' => 'The current user is not authorized to perform the requested action.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::USER_AUTH_METHOD_UNSUPPORTED => [
|
||||
'name' => Exception::USER_AUTH_METHOD_UNSUPPORTED,
|
||||
'description' => 'The requested authentication method is either disabled or unsupported. Please check the supported authentication methods in the Appwrite console.',
|
||||
'code' => 501,
|
||||
],
|
||||
|
||||
/** Teams */
|
||||
Exception::TEAM_NOT_FOUND => [
|
||||
'name' => Exception::TEAM_NOT_FOUND,
|
||||
'description' => 'Team with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TEAM_INVITE_ALREADY_EXISTS => [
|
||||
'name' => Exception::TEAM_INVITE_ALREADY_EXISTS,
|
||||
'description' => 'The current user has already received an invitation to join the team.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::TEAM_INVITE_NOT_FOUND => [
|
||||
'name' => Exception::TEAM_INVITE_NOT_FOUND,
|
||||
'description' => 'The requested team invitation could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TEAM_INVALID_SECRET => [
|
||||
'name' => Exception::TEAM_INVALID_SECRET,
|
||||
'description' => 'The team invitation secret is invalid.',
|
||||
'code' => 401,
|
||||
],
|
||||
Exception::TEAM_MEMBERSHIP_MISMATCH => [
|
||||
'name' => Exception::TEAM_MEMBERSHIP_MISMATCH,
|
||||
'description' => 'The membership ID does not belong to the team ID.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TEAM_INVITE_MISMATCH => [
|
||||
'name' => Exception::TEAM_INVITE_MISMATCH,
|
||||
'description' => 'The invite does not belong to the current user.',
|
||||
'code' => 401,
|
||||
],
|
||||
|
||||
|
||||
/** Membership */
|
||||
Exception::MEMBERSHIP_NOT_FOUND => [
|
||||
'name' => Exception::MEMBERSHIP_NOT_FOUND,
|
||||
'description' => 'Membership with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
|
||||
/** Avatars */
|
||||
Exception::AVATAR_SET_NOT_FOUND => [
|
||||
'name' => Exception::AVATAR_SET_NOT_FOUND,
|
||||
'description' => 'The requested avatar set could not be found.',
|
||||
'code' => 404
|
||||
],
|
||||
Exception::AVATAR_NOT_FOUND => [
|
||||
'name' => Exception::AVATAR_NOT_FOUND,
|
||||
'description' => 'The request avatar could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::AVATAR_IMAGE_NOT_FOUND => [
|
||||
'name' => Exception::AVATAR_IMAGE_NOT_FOUND,
|
||||
'description' => 'The requested image was not found at the URL.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::AVATAR_REMOTE_URL_FAILED => [
|
||||
'name' => Exception::AVATAR_REMOTE_URL_FAILED,
|
||||
'description' => 'Failed to fetch favicon from the requested URL.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::AVATAR_ICON_NOT_FOUND => [
|
||||
'name' => Exception::AVATAR_ICON_NOT_FOUND,
|
||||
'description' => 'The requested favicon could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
|
||||
/** Storage */
|
||||
Exception::STORAGE_FILE_NOT_FOUND => [
|
||||
'name' => Exception::STORAGE_FILE_NOT_FOUND,
|
||||
'description' => 'The requested file could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::STORAGE_DEVICE_NOT_FOUND => [
|
||||
'name' => Exception::STORAGE_DEVICE_NOT_FOUND,
|
||||
'description' => 'The requested storage device could not be found.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::STORAGE_FILE_EMPTY => [
|
||||
'name' => Exception::STORAGE_FILE_EMPTY,
|
||||
'description' => 'Empty file passed to the endpoint.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::STORAGE_FILE_TYPE_UNSUPPORTED => [
|
||||
'name' => Exception::STORAGE_FILE_TYPE_UNSUPPORTED,
|
||||
'description' => 'The file type is not supported.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::STORAGE_INVALID_FILE_SIZE => [
|
||||
'name' => Exception::STORAGE_INVALID_FILE_SIZE,
|
||||
'description' => 'The file size is either not valid or exceeds the maximum allowed size. Please check the file or the value of the _APP_STORAGE_LIMIT environment variable.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::STORAGE_INVALID_FILE => [
|
||||
'name' => Exception::STORAGE_INVALID_FILE,
|
||||
'description' => 'The uploaded file is invalid. Please check the file and try again.',
|
||||
'code' => 403,
|
||||
],
|
||||
Exception::STORAGE_BUCKET_ALREADY_EXISTS => [
|
||||
'name' => Exception::STORAGE_BUCKET_ALREADY_EXISTS,
|
||||
'description' => 'A storage bucket with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::STORAGE_BUCKET_NOT_FOUND => [
|
||||
'name' => Exception::STORAGE_BUCKET_NOT_FOUND,
|
||||
'description' => 'Storage bucket with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::STORAGE_INVALID_CONTENT_RANGE => [
|
||||
'name' => Exception::STORAGE_INVALID_CONTENT_RANGE,
|
||||
'description' => 'The content range is invalid. Please check the value of the Content-Range header.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::STORAGE_INVALID_RANGE => [
|
||||
'name' => Exception::STORAGE_INVALID_RANGE,
|
||||
'description' => 'The requested range is not satisfiable. Please check the value of the Range header.',
|
||||
'code' => 416,
|
||||
],
|
||||
|
||||
/** Functions */
|
||||
Exception::FUNCTION_NOT_FOUND => [
|
||||
'name' => Exception::FUNCTION_NOT_FOUND,
|
||||
'description' => 'Function with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::FUNCTION_RUNTIME_UNSUPPORTED => [
|
||||
'name' => Exception::FUNCTION_RUNTIME_UNSUPPORTED,
|
||||
'description' => 'The requested runtime is either inactive or unsupported. Please check the value of the _APP_FUNCTIONS_RUNTIMES environment variable.',
|
||||
'code' => 404,
|
||||
],
|
||||
|
||||
/** Builds */
|
||||
Exception::BUILD_NOT_FOUND => [
|
||||
'name' => Exception::BUILD_NOT_FOUND,
|
||||
'description' => 'Build with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::BUILD_NOT_READY => [
|
||||
'name' => Exception::BUILD_NOT_READY,
|
||||
'description' => 'Build with the requested ID is builing and not ready for execution.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::BUILD_IN_PROGRESS => [
|
||||
'name' => Exception::BUILD_IN_PROGRESS,
|
||||
'description' => 'Build with the requested ID is already in progress. Please wait before you can retry.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Deployments */
|
||||
Exception::DEPLOYMENT_NOT_FOUND => [
|
||||
'name' => Exception::DEPLOYMENT_NOT_FOUND,
|
||||
'description' => 'Deployment with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
|
||||
/** Executions */
|
||||
Exception::EXECUTION_NOT_FOUND => [
|
||||
'name' => Exception::EXECUTION_NOT_FOUND,
|
||||
'description' => 'Execution with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
|
||||
/** Collections */
|
||||
Exception::COLLECTION_NOT_FOUND => [
|
||||
'name' => Exception::COLLECTION_NOT_FOUND,
|
||||
'description' => 'Collection with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::COLLECTION_ALREADY_EXISTS => [
|
||||
'name' => Exception::COLLECTION_ALREADY_EXISTS,
|
||||
'description' => 'A collection with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::COLLECTION_LIMIT_EXCEEDED => [
|
||||
'name' => Exception::COLLECTION_LIMIT_EXCEEDED,
|
||||
'description' => 'The maximum number of collections has been reached.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Documents */
|
||||
Exception::DOCUMENT_NOT_FOUND => [
|
||||
'name' => Exception::DOCUMENT_NOT_FOUND,
|
||||
'description' => 'Document with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::DOCUMENT_INVALID_STRUCTURE => [
|
||||
'name' => Exception::DOCUMENT_INVALID_STRUCTURE,
|
||||
'description' => 'The document structure is invalid. Please ensure the attributes match the collection definition.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::DOCUMENT_MISSING_PAYLOAD => [
|
||||
'name' => Exception::DOCUMENT_MISSING_PAYLOAD,
|
||||
'description' => 'The document payload is missing.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::DOCUMENT_ALREADY_EXISTS => [
|
||||
'name' => Exception::DOCUMENT_ALREADY_EXISTS,
|
||||
'description' => 'Document with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
|
||||
/** Attributes */
|
||||
Exception::ATTRIBUTE_NOT_FOUND => [
|
||||
'name' => Exception::ATTRIBUTE_NOT_FOUND,
|
||||
'description' => 'Attribute with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::ATTRIBUTE_UNKNOWN => [
|
||||
'name' => Exception::ATTRIBUTE_UNKNOWN,
|
||||
'description' => 'The attribute required for the index could not be found. Please confirm all your attributes are in the <span class="tag">available</span> state.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::ATTRIBUTE_NOT_AVAILABLE => [
|
||||
'name' => Exception::ATTRIBUTE_NOT_AVAILABLE,
|
||||
'description' => 'The requested attribute is not yet <span class="tag">available</span>. Please try again later.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::ATTRIBUTE_FORMAT_UNSUPPORTED => [
|
||||
'name' => Exception::ATTRIBUTE_FORMAT_UNSUPPORTED,
|
||||
'description' => 'The requested attribute format is not supported.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED => [
|
||||
'name' => Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED,
|
||||
'description' => 'Default values cannot be set for <span class="tag">array</span> and <span class="tag">required</span> attributes.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::ATTRIBUTE_ALREADY_EXISTS => [
|
||||
'name' => Exception::ATTRIBUTE_ALREADY_EXISTS,
|
||||
'description' => 'Attribute with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::ATTRIBUTE_LIMIT_EXCEEDED => [
|
||||
'name' => Exception::ATTRIBUTE_LIMIT_EXCEEDED,
|
||||
'description' => 'The maximum number of attributes has been reached.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::ATTRIBUTE_VALUE_INVALID => [
|
||||
'name' => Exception::ATTRIBUTE_VALUE_INVALID,
|
||||
'description' => 'The attribute value is invalid. Please check the type, range and value of the attribute.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Indexes */
|
||||
Exception::INDEX_NOT_FOUND => [
|
||||
'name' => Exception::INDEX_NOT_FOUND,
|
||||
'description' => 'Index with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::INDEX_LIMIT_EXCEEDED => [
|
||||
'name' => Exception::INDEX_LIMIT_EXCEEDED,
|
||||
'description' => 'The maximum number of indexes has been reached.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::INDEX_ALREADY_EXISTS => [
|
||||
'name' => Exception::INDEX_ALREADY_EXISTS,
|
||||
'description' => 'Index with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
|
||||
/** Project Errors */
|
||||
Exception::PROJECT_NOT_FOUND => [
|
||||
'name' => Exception::PROJECT_NOT_FOUND,
|
||||
'description' => 'Project with the requested ID could not be found. Please check the value of the X-Appwrite-Project header to ensure the correct project ID is being used.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::PROJECT_UNKNOWN => [
|
||||
'name' => Exception::PROJECT_UNKNOWN,
|
||||
'description' => 'The project ID is either missing or not valid. Please check the value of the X-Appwrite-Project header to ensure the correct project ID is being used.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::PROJECT_PROVIDER_DISABLED => [
|
||||
'name' => Exception::PROJECT_PROVIDER_DISABLED,
|
||||
'description' => 'The chosen OAuth provider is disabled. You can enable the OAuth provider using the Appwrite console.',
|
||||
'code' => 412,
|
||||
],
|
||||
Exception::PROJECT_PROVIDER_UNSUPPORTED => [
|
||||
'name' => Exception::PROJECT_PROVIDER_UNSUPPORTED,
|
||||
'description' => 'The chosen OAuth provider is unsupported. Please check <a href="/docs/client/account?sdk=web-default#accountCreateOAuth2Session"> the docs</a> for the complete list of supported OAuth providers.',
|
||||
'code' => 501,
|
||||
],
|
||||
Exception::PROJECT_INVALID_SUCCESS_URL => [
|
||||
'name' => Exception::PROJECT_INVALID_SUCCESS_URL,
|
||||
'description' => 'Invalid URL received for OAuth success redirect.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::PROJECT_INVALID_FAILURE_URL => [
|
||||
'name' => Exception::PROJECT_INVALID_FAILURE_URL,
|
||||
'description' => 'Invalid URL received for OAuth failure redirect.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::PROJECT_MISSING_USER_ID => [
|
||||
'name' => Exception::PROJECT_MISSING_USER_ID,
|
||||
'description' => 'Failed to obtain user ID from the OAuth provider.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::WEBHOOK_NOT_FOUND => [
|
||||
'name' => Exception::WEBHOOK_NOT_FOUND,
|
||||
'description' => 'Webhook with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::KEY_NOT_FOUND => [
|
||||
'name' => Exception::KEY_NOT_FOUND,
|
||||
'description' => 'Key with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::PLATFORM_NOT_FOUND => [
|
||||
'name' => Exception::PLATFORM_NOT_FOUND,
|
||||
'description' => 'Platform with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::DOMAIN_NOT_FOUND => [
|
||||
'name' => Exception::DOMAIN_NOT_FOUND,
|
||||
'description' => 'Domain with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::DOMAIN_ALREADY_EXISTS => [
|
||||
'name' => Exception::DOMAIN_ALREADY_EXISTS,
|
||||
'description' => 'A Domain with the requested ID already exists.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::DOMAIN_VERIFICATION_FAILED => [
|
||||
'name' => Exception::DOMAIN_VERIFICATION_FAILED,
|
||||
'description' => 'Domain verification for the requested domain has failed.',
|
||||
'code' => 401,
|
||||
]
|
||||
];
|
||||
@@ -27,6 +27,21 @@ return [
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => '',
|
||||
],
|
||||
'users.update.email' => [
|
||||
'description' => 'This event triggers when the user email address is updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => '',
|
||||
],
|
||||
'users.update.name' => [
|
||||
'description' => 'This event triggers when the user name is updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => '',
|
||||
],
|
||||
'users.update.password' => [
|
||||
'description' => 'This event triggers when the user password is updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
'note' => '',
|
||||
],
|
||||
'account.update.prefs' => [
|
||||
'description' => 'This event triggers when the account preferences are updated.',
|
||||
'model' => Response::MODEL_USER,
|
||||
@@ -67,6 +82,11 @@ return [
|
||||
'model' => Response::MODEL_SESSION,
|
||||
'note' => '',
|
||||
],
|
||||
'account.sessions.update' => [
|
||||
'description' => 'This event triggers when the account session is updated.',
|
||||
'model' => Response::MODEL_SESSION,
|
||||
'note' => '',
|
||||
],
|
||||
'database.collections.create' => [
|
||||
'description' => 'This event triggers when a database collection is created.',
|
||||
'model' => Response::MODEL_COLLECTION,
|
||||
@@ -82,6 +102,26 @@ return [
|
||||
'model' => Response::MODEL_COLLECTION,
|
||||
'note' => '',
|
||||
],
|
||||
'database.attributes.create' => [
|
||||
'description' => 'This event triggers when a collection attribute is created.',
|
||||
'model' => Response::MODEL_ATTRIBUTE,
|
||||
'note' => '',
|
||||
],
|
||||
'database.attributes.delete' => [
|
||||
'description' => 'This event triggers when a collection attribute is deleted.',
|
||||
'model' => Response::MODEL_ATTRIBUTE,
|
||||
'note' => '',
|
||||
],
|
||||
'database.indexes.create' => [
|
||||
'description' => 'This event triggers when a collection index is created.',
|
||||
'model' => Response::MODEL_INDEX,
|
||||
'note' => '',
|
||||
],
|
||||
'database.indexes.delete' => [
|
||||
'description' => 'This event triggers when a collection index is deleted.',
|
||||
'model' => Response::MODEL_INDEX,
|
||||
'note' => '',
|
||||
],
|
||||
'database.documents.create' => [
|
||||
'description' => 'This event triggers when a database document is created.',
|
||||
'model' => Response::MODEL_DOCUMENT,
|
||||
@@ -112,18 +152,18 @@ return [
|
||||
'model' => Response::MODEL_ANY,
|
||||
'note' => 'version >= 0.7',
|
||||
],
|
||||
'functions.tags.create' => [
|
||||
'description' => 'This event triggers when a function tag is created.',
|
||||
'model' => Response::MODEL_TAG,
|
||||
'functions.deployments.create' => [
|
||||
'description' => 'This event triggers when a function delpoyment is created.',
|
||||
'model' => Response::MODEL_DEPLOYMENT,
|
||||
'note' => 'version >= 0.7',
|
||||
],
|
||||
'functions.tags.update' => [
|
||||
'description' => 'This event triggers when a function tag is updated.',
|
||||
'functions.deployments.update' => [
|
||||
'description' => 'This event triggers when a function delpoyment is updated.',
|
||||
'model' => Response::MODEL_FUNCTION,
|
||||
'note' => 'version >= 0.7',
|
||||
],
|
||||
'functions.tags.delete' => [
|
||||
'description' => 'This event triggers when a function tag is deleted.',
|
||||
'functions.deployments.delete' => [
|
||||
'description' => 'This event triggers when a function delpoyment is deleted.',
|
||||
'model' => Response::MODEL_ANY,
|
||||
'note' => 'version >= 0.7',
|
||||
],
|
||||
@@ -152,6 +192,21 @@ return [
|
||||
'model' => Response::MODEL_FILE,
|
||||
'note' => '',
|
||||
],
|
||||
'storage.buckets.create' => [
|
||||
'description' => 'This event triggers when a storage bucket is created.',
|
||||
'model' => Response::MODEL_BUCKET,
|
||||
'note' => '',
|
||||
],
|
||||
'storage.buckets.update' => [
|
||||
'description' => 'This event triggers when a storage bucket is updated.',
|
||||
'model' => Response::MODEL_BUCKET,
|
||||
'note' => '',
|
||||
],
|
||||
'storage.buckets.delete' => [
|
||||
'description' => 'This event triggers when a storage bucket is deleted.',
|
||||
'model' => Response::MODEL_BUCKET,
|
||||
'note' => '',
|
||||
],
|
||||
'users.create' => [
|
||||
'description' => 'This event triggers when a user is created from the users API.',
|
||||
'model' => Response::MODEL_USER,
|
||||
|
||||
@@ -37,16 +37,16 @@ return [
|
||||
'kn', // Kannada
|
||||
'km', // Khmer
|
||||
'ko', // Korean
|
||||
'la', // Latin
|
||||
'lb', // Luxembourgish
|
||||
'lt', // Lithuanian
|
||||
'lv', // Latvian
|
||||
'ml', // Malayalam
|
||||
'mr', // Marathi
|
||||
'ms', // Malay
|
||||
'nb', // Norwegian - Bokmål
|
||||
'nb', // Norwegian bokmål
|
||||
'nl', // Dutch
|
||||
'nn', // Norwegian (nynorsk)
|
||||
'no', // Norwegian (bokmål)
|
||||
'nn', // Norwegian nynorsk
|
||||
'ne', // Nepali
|
||||
'or', // Oriya
|
||||
'tl', // Filipino
|
||||
@@ -61,9 +61,11 @@ return [
|
||||
'si', // Sinhala
|
||||
'sk', // Slovakia
|
||||
'sl', // Slovenian
|
||||
'sn', // Shona
|
||||
'sq', // Albanian
|
||||
'sv', // Swedish
|
||||
'ta', // Tamil
|
||||
'te', // Telugu
|
||||
'th', // Thai
|
||||
'tr', // Turkish
|
||||
'uk', // Ukrainian
|
||||
|
||||
@@ -593,11 +593,6 @@ return [
|
||||
"name" => "Norwegian Nynorsk",
|
||||
"nativeName" => "Norsk nynorsk"
|
||||
],
|
||||
[
|
||||
"code" => "no",
|
||||
"name" => "Norwegian",
|
||||
"nativeName" => "Norsk"
|
||||
],
|
||||
[
|
||||
"code" => "nr",
|
||||
"name" => "South Ndebele",
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
"settings.locale": "bn",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s টীম",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "বিষয়",
|
||||
"emails.verification.hello": "নমস্কার {{name}}",
|
||||
"emails.verification.body": "এই লিঙ্কের মাধ্যমে ইমেইল যাচাই করুন।",
|
||||
"emails.verification.footer": "আপনি যদি এই ঠিকানা যাচাই করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
|
||||
"emails.verification.thanks": "ধন্যবাদ",
|
||||
"emails.verification.signature": "{{project}} টীম",
|
||||
"emails.magicSession.subject": "লগ ইন",
|
||||
"emails.magicSession.hello": "নমস্কার",
|
||||
"emails.magicSession.body": "এই লিঙ্কের মাধ্যমে লগ ইন করুন।",
|
||||
"emails.magicSession.footer": "আপনি যদি এই ইমেলটি ব্যবহার করে লগইন করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
|
||||
"emails.magicSession.thanks": "ধন্যবাদ",
|
||||
"emails.magicSession.signature": "{{project}} টীম",
|
||||
"emails.recovery.subject": "পাসওয়ার্ড রিসেট",
|
||||
"emails.recovery.hello": "নমস্কার {{name}}",
|
||||
"emails.recovery.body": "এই লিঙ্কের মাধ্যমে আপনার {{project}} পাসওয়ার্ড পুনরায় সেট করুন।",
|
||||
"emails.recovery.footer": "আপনি যদি আপনার পাসওয়ার্ড পুনরায় সেট করতে না বলেন, তাহলে আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
|
||||
"emails.recovery.thanks": "ধন্যবাদ",
|
||||
"emails.recovery.signature": "{{project}} টীম",
|
||||
"emails.invitation.subject": "%s টিমকে %s তে আমন্ত্রণ জানান",
|
||||
"emails.invitation.hello": "নমস্কার",
|
||||
"emails.invitation.body": "এই মেইলটি আপনাকে পাঠানো হয়েছে কারণ {{owner}} আপনাকে {{project}} এর সাথে যুক্ত {{team}} টিমের সদস্য হওয়ার জন্য আমন্ত্রণ জানাতে চেয়েছিলেন।",
|
||||
"emails.invitation.footer": "যদি এটি আপনার জন্য প্রয়োজনীয় না হয়, আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
|
||||
"emails.invitation.thanks": "ধন্যবাদ",
|
||||
"emails.invitation.signature": "{{project}} টীম",
|
||||
"locale.country.unknown": "অজানা",
|
||||
"countries.af": "আফগানিস্তান",
|
||||
"countries.ao": "অ্যাঙ্গোলা",
|
||||
@@ -229,4 +229,4 @@
|
||||
"continents.na": "উত্তর আমেরিকা",
|
||||
"continents.oc": "ওশেনিয়া",
|
||||
"continents.sa": "দক্ষিণ আমেরিকা"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
{
|
||||
"settings.inspire": "\"هنر خردمند بودن، هنر دانستن چیزی است که باید از آن غافل شد.\"",
|
||||
"settings.inspire": "\"هنر خردمند بودن این است که بدانید چه چیزی را نادیده بگیرید.\"",
|
||||
"settings.locale": "fa",
|
||||
"settings.direction": "rtl",
|
||||
"emails.sender": "تیم %s",
|
||||
"emails.verification.subject": "تأیید حساب",
|
||||
"emails.verification.hello": "سلام {{name}}",
|
||||
"emails.verification.body": "برای تأیید حسابتان پیوند زیر را دنبال کنید.",
|
||||
"emails.verification.footer": "اگر شما درخواست تأیید حساب ندادهاید، میتوانید این ایمیل را نادیده بگیرید.",
|
||||
"emails.verification.body": "برای تأیید ایمیلتان پیوند زیر را دنبال کنید.",
|
||||
"emails.verification.footer": "اگر شما درخواست تأیید حساب ندادهاید، میتوانید این پیام را نادیده بگیرید.",
|
||||
"emails.verification.thanks": "سپاس فراوان",
|
||||
"emails.verification.signature": "تیم {{name}}",
|
||||
"emails.magicSession.subject": "ورود به حساب کاربری",
|
||||
"emails.magicSession.hello": "سلام،",
|
||||
"emails.magicSession.body": "برای ورود به حسابتان پیوند زیر را دنبال کنید.",
|
||||
"emails.magicSession.footer": "اگر شما درخواست ورود به حساب کاربری ندادهاید، میتوانید این ایمیل را نادیده بگیرید.",
|
||||
"emails.magicSession.footer": "اگر شما درخواست ورود به حساب کاربری با استفاده از این ایمیل را ندادهاید، میتوانید این پیام را نادیده بگیرید.",
|
||||
"emails.magicSession.thanks": "سپاس فراوان",
|
||||
"emails.magicSession.signature": "تیم {{name}}",
|
||||
"emails.recovery.subject": "بازیابی گذرواژه",
|
||||
"emails.recovery.hello": "سلام {{name}}",
|
||||
"emails.recovery.body": "برای بازیابی گذرواژهتان پیوند زیر را دنبال کنید.",
|
||||
"emails.recovery.footer": "اگر شما درخواست بازیابی گذرواژه ندادهاید، میتوانید این ایمیل را نادیده بگیرید.",
|
||||
"emails.recovery.footer": "اگر شما درخواست بازیابی گذرواژه ندادهاید، میتوانید این پیام را نادیده بگیرید.",
|
||||
"emails.recovery.thanks": "سپاس فراوان",
|
||||
"emails.recovery.signature": "تیم {{name}}",
|
||||
"emails.invitation.subject": "دعوت به تیم %s در %s",
|
||||
|
||||
@@ -28,205 +28,205 @@
|
||||
"emails.invitation.thanks": "Go raibh maith agat",
|
||||
"emails.invitation.signature": "{{project}} foireann",
|
||||
"locale.country.unknown": "Neamhaithnid",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "United Arab Emirates",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua and Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbaijan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgium",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesh",
|
||||
"countries.bg": "Bulgaria",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnia and Herzegovina",
|
||||
"countries.by": "Belarus",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivia",
|
||||
"countries.br": "Brazil",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Central African Republic",
|
||||
"countries.ca": "Canada",
|
||||
"countries.ch": "Switzerland",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "China",
|
||||
"countries.ci": "Ivory Coast",
|
||||
"countries.cm": "Cameroon",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republic of the Congo",
|
||||
"countries.co": "Colombia",
|
||||
"countries.km": "Comoros",
|
||||
"countries.af": "An Afganastáin",
|
||||
"countries.ao": "Angóla",
|
||||
"countries.al": "Albáin",
|
||||
"countries.ad": "Andóra",
|
||||
"countries.ae": "Aontas na nÉimíríochtaí Arabacha",
|
||||
"countries.ar": "Airgintín",
|
||||
"countries.am": "Airméin",
|
||||
"countries.ag": "Antigua agus Barbúda",
|
||||
"countries.au": "Astráil",
|
||||
"countries.at": "Ostair",
|
||||
"countries.az": "Asarbaiseáin",
|
||||
"countries.bi": "An Bhurúin",
|
||||
"countries.be": "An Bheilg",
|
||||
"countries.bj": "Beinin",
|
||||
"countries.bf": "Buircíne Fasó",
|
||||
"countries.bd": "An Bhanglaidéis",
|
||||
"countries.bg": "An Bhulgáir",
|
||||
"countries.bh": "Bairéin",
|
||||
"countries.bs": "Na Bahámaí",
|
||||
"countries.ba": "An Bhoisnia agus an Heirseagaivéin",
|
||||
"countries.by": "An Bhealarúis",
|
||||
"countries.bz": "An Bheilís",
|
||||
"countries.bo": "An Bholaiv",
|
||||
"countries.br": "An Bhrasaíl",
|
||||
"countries.bb": "Barbadós",
|
||||
"countries.bn": "Brúiné",
|
||||
"countries.bt": "An Bhútáin",
|
||||
"countries.bw": "An Bhotsuáin",
|
||||
"countries.cf": "Poblacht na hAfraice Láir",
|
||||
"countries.ca": "Ceanada",
|
||||
"countries.ch": "An Eilvéis",
|
||||
"countries.cl": "An tSile",
|
||||
"countries.cn": "An tSín",
|
||||
"countries.ci": "Poblacht Côte d’Ivoire",
|
||||
"countries.cm": "Camarún",
|
||||
"countries.cd": "Poblacht Dhaonlathach an Chongó",
|
||||
"countries.cg": "Poblacht an Chongó",
|
||||
"countries.co": "An Cholóim",
|
||||
"countries.km": "Oileáin Chomóra",
|
||||
"countries.cv": "Cape Verde",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Cuba",
|
||||
"countries.cy": "Cyprus",
|
||||
"countries.cz": "Czechia",
|
||||
"countries.de": "Germany",
|
||||
"countries.cr": "Cósta Ríce",
|
||||
"countries.cu": "Cúba",
|
||||
"countries.cy": "An Chipir",
|
||||
"countries.cz": "An tSeicia",
|
||||
"countries.de": "An Ghearmáin",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Denmark",
|
||||
"countries.do": "Dominican Republic",
|
||||
"countries.dz": "Algeria",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Egypt",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spain",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Ethiopia",
|
||||
"countries.fi": "Finland",
|
||||
"countries.fj": "Fiji",
|
||||
"countries.fr": "France",
|
||||
"countries.fm": "Micronesia",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "United Kingdom",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Equatorial Guinea",
|
||||
"countries.gr": "Greece",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Hungary",
|
||||
"countries.id": "Indonesia",
|
||||
"countries.dm": "Doiminice",
|
||||
"countries.dk": "An Danmhairg",
|
||||
"countries.do": "An Phoblacht Dhoiminiceach",
|
||||
"countries.dz": "An Ailgéir",
|
||||
"countries.ec": "Eacuadór",
|
||||
"countries.eg": "An Éigipt",
|
||||
"countries.er": "An Eiritré",
|
||||
"countries.es": "An Spáinn",
|
||||
"countries.ee": "An Eastóin",
|
||||
"countries.et": "An Aetóip",
|
||||
"countries.fi": "An Fhionlainn",
|
||||
"countries.fj": "Fidsí",
|
||||
"countries.fr": "An Fhrainc",
|
||||
"countries.fm": "An Mhicrinéis",
|
||||
"countries.ga": "An Ghabúin",
|
||||
"countries.gb": "An Ríocht Aontaithe",
|
||||
"countries.ge": "An tSeoirsia",
|
||||
"countries.gh": "Gána",
|
||||
"countries.gn": "An Ghuine",
|
||||
"countries.gm": "An Ghaimbia",
|
||||
"countries.gw": "Guine Bissau",
|
||||
"countries.gq": "An Ghuine Mheánchiorclach",
|
||||
"countries.gr": "An Ghréig",
|
||||
"countries.gd": "Greanáda",
|
||||
"countries.gt": "Guatamala",
|
||||
"countries.gy": "An Ghuáin",
|
||||
"countries.hn": "Hondúras",
|
||||
"countries.hr": "An Chróit",
|
||||
"countries.ht": "Háítí",
|
||||
"countries.hu": "An Ungáir",
|
||||
"countries.id": "An Indinéis",
|
||||
"countries.in": "India",
|
||||
"countries.ie": "Ireland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Iraq",
|
||||
"countries.is": "Iceland",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italy",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kazakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
"countries.kg": "Kyrgyzstan",
|
||||
"countries.kh": "Cambodia",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts and Nevis",
|
||||
"countries.kr": "South Korea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.ie": "Éire",
|
||||
"countries.ir": "An Iaráin",
|
||||
"countries.iq": "An Iaráic",
|
||||
"countries.is": "An Íoslainn",
|
||||
"countries.il": "Iosrael",
|
||||
"countries.it": "An Iodáil",
|
||||
"countries.jm": "Iamáice",
|
||||
"countries.jo": "An Iordáin",
|
||||
"countries.jp": "An tSeapáin",
|
||||
"countries.kz": "An Chasacstáin",
|
||||
"countries.ke": "An Chéinia",
|
||||
"countries.kg": "An Chirgeastáin",
|
||||
"countries.kh": "An Chambóid",
|
||||
"countries.ki": "Ciribeas",
|
||||
"countries.kn": "San Críostóir-Nimheas",
|
||||
"countries.kr": "An Chóiré Theas",
|
||||
"countries.kw": "Cuáit",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Lebanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libya",
|
||||
"countries.lb": "An Liobáin",
|
||||
"countries.lr": "An Libéir",
|
||||
"countries.ly": "An Libia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Lithuania",
|
||||
"countries.lu": "Luxembourg",
|
||||
"countries.lv": "Latvia",
|
||||
"countries.ma": "Morocco",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldova",
|
||||
"countries.li": "Lichtinstéin",
|
||||
"countries.lk": "Srí Lanca",
|
||||
"countries.ls": "Leosóta",
|
||||
"countries.lt": "An Liotuáin",
|
||||
"countries.lu": "Lucsamburg",
|
||||
"countries.lv": "An Laitvia",
|
||||
"countries.ma": "Maracó",
|
||||
"countries.mc": "Monacó",
|
||||
"countries.md": "An Mholdóiv",
|
||||
"countries.mg": "Madagascar",
|
||||
"countries.mv": "Maldives",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mh": "Marshall Islands",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambique",
|
||||
"countries.mr": "Mauritania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysia",
|
||||
"countries.na": "Namibia",
|
||||
"countries.mv": "Oileáin Mhaildíve",
|
||||
"countries.mx": "Meicsiceo",
|
||||
"countries.mh": "Oileáin Marshall",
|
||||
"countries.mk": "An Mhacadóin",
|
||||
"countries.ml": "Mailí",
|
||||
"countries.mt": "Málta",
|
||||
"countries.mm": "Maenmar",
|
||||
"countries.me": "Montainéagró",
|
||||
"countries.mn": "An Mhongóil",
|
||||
"countries.mz": "Mósaimbíc",
|
||||
"countries.mr": "An Mháratáin",
|
||||
"countries.mu": "Oileán Mhuirís",
|
||||
"countries.mw": "Malávach",
|
||||
"countries.my": "An Mhalaeisia",
|
||||
"countries.na": "An Namaib",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Netherlands",
|
||||
"countries.no": "Norway",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "New Zealand",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.ng": "An Nigéir",
|
||||
"countries.ni": "Nicearagua",
|
||||
"countries.nl": "An Ísiltír",
|
||||
"countries.no": "An Iorua",
|
||||
"countries.np": "Neipeal",
|
||||
"countries.nr": "Nárú",
|
||||
"countries.nz": "An Nua-Shéalainn",
|
||||
"countries.om": "Óman",
|
||||
"countries.pk": "An Phacastáin",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Philippines",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua New Guinea",
|
||||
"countries.pl": "Poland",
|
||||
"countries.kp": "North Korea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Qatar",
|
||||
"countries.ro": "Romania",
|
||||
"countries.ru": "Russia",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudi Arabia",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapore",
|
||||
"countries.sb": "Solomon Islands",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "South Sudan",
|
||||
"countries.st": "São Tomé and Príncipe",
|
||||
"countries.sr": "Suriname",
|
||||
"countries.sk": "Slovakia",
|
||||
"countries.si": "Slovenia",
|
||||
"countries.se": "Sweden",
|
||||
"countries.sz": "Swaziland",
|
||||
"countries.sc": "Seychelles",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Chad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tajikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.pe": "Peiriú",
|
||||
"countries.ph": "Na hOileáin Fhilipíneacha",
|
||||
"countries.pw": "Oileáin Palau",
|
||||
"countries.pg": "Nua-Ghuine Phapua",
|
||||
"countries.pl": "An Pholainn",
|
||||
"countries.kp": "An Chóiré Thuaidh",
|
||||
"countries.pt": "An Phortaingéil",
|
||||
"countries.py": "Paragua",
|
||||
"countries.qa": "Catar",
|
||||
"countries.ro": "An Rómáin",
|
||||
"countries.ru": "An Rúis",
|
||||
"countries.rw": "Ruanda",
|
||||
"countries.sa": "An Araib Shádach",
|
||||
"countries.sd": "An tSúdáin",
|
||||
"countries.sn": "An tSeineagáil",
|
||||
"countries.sg": "Singeapór",
|
||||
"countries.sb": "Oileáin Sholaimh",
|
||||
"countries.sl": "Siarra Leon",
|
||||
"countries.sv": "An tSalvadóir",
|
||||
"countries.sm": "San Mairíne",
|
||||
"countries.so": "An tSomáil",
|
||||
"countries.rs": "An tSeirbia",
|
||||
"countries.ss": "An tSúdáin Theas",
|
||||
"countries.st": "São Tomé agus Príncipe",
|
||||
"countries.sr": "Suranam",
|
||||
"countries.sk": "An tSlóvaic",
|
||||
"countries.si": "An tSlóivéin",
|
||||
"countries.se": "An tSualainn",
|
||||
"countries.sz": "An tSuasalainn",
|
||||
"countries.sc": "Na Séiséil",
|
||||
"countries.sy": "An tSiria",
|
||||
"countries.td": "Sead",
|
||||
"countries.tg": "Tóga",
|
||||
"countries.th": "An Téalainn",
|
||||
"countries.tj": "An Táidsíceastáin",
|
||||
"countries.tm": "An Tuircméanastáin",
|
||||
"countries.tl": "Tíomór Thoir",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad and Tobago",
|
||||
"countries.tn": "Tunisia",
|
||||
"countries.tr": "Turkey",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.tt": "Oileán na Tríonóide agus Tobága",
|
||||
"countries.tn": "An Túinéis",
|
||||
"countries.tr": "An Tuirc",
|
||||
"countries.tv": "Túvalú",
|
||||
"countries.tz": "An Tansáin",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "United States",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatican City",
|
||||
"countries.vc": "Saint Vincent and the Grenadines",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "South Africa",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Africa",
|
||||
"continents.an": "Antarctica",
|
||||
"continents.as": "Asia",
|
||||
"continents.eu": "Europe",
|
||||
"continents.na": "North America",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "South America"
|
||||
"countries.ua": "An Úcráin",
|
||||
"countries.uy": "Uragua",
|
||||
"countries.us": "Na Stáit Aontaithe",
|
||||
"countries.uz": "An Úisbéiceastáin",
|
||||
"countries.va": "Cathair na Vatacáine",
|
||||
"countries.vc": "San Uinseann agus na Greanáidíní",
|
||||
"countries.ve": "Veiniséala",
|
||||
"countries.vn": "Vítneam",
|
||||
"countries.vu": "Vanuatú",
|
||||
"countries.ws": "Samó",
|
||||
"countries.ye": "Éimin",
|
||||
"countries.za": "An Afraic Theas",
|
||||
"countries.zm": "An tSaimbia",
|
||||
"countries.zw": "An tSiombáib",
|
||||
"continents.af": "An Afraic",
|
||||
"continents.an": "Antartaice",
|
||||
"continents.as": "An Áise",
|
||||
"continents.eu": "An Eoraip",
|
||||
"continents.na": "Meiriceá Thuaidh",
|
||||
"continents.oc": "An Aigéine",
|
||||
"continents.sa": "Meiriceá Theas"
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
{
|
||||
"settings.inspire": "\"बुद्धिमान होने की कला यह जानने की कला है कि क्या अनदेखा करना चाहिए |\"",
|
||||
"settings.inspire": "\"बुद्धिमान होने की कला यह जानने की कला है कि क्या अनदेखा किया जाए |\"",
|
||||
"settings.locale": "hi",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s टीम",
|
||||
"emails.verification.subject": "खाता सत्यापन",
|
||||
"emails.verification.subject": "अकाउंट वेरिफिकेशन ",
|
||||
"emails.verification.hello": "नमस्ते {{name}}",
|
||||
"emails.verification.body": "इस लिंक के माध्यम से ईमेल सत्यापित कीजिये।",
|
||||
"emails.verification.footer": "यदि आपने इस पते को सत्यापित करने के लिए नहीं कहा है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.verification.body": "इस लिंक के माध्यम से अपने ईमेल को सत्यापित कीजिये।",
|
||||
"emails.verification.footer": "यदि आपने इस पते को सत्यापित नहीं करना चाहते है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.verification.thanks": "धन्यवाद",
|
||||
"emails.verification.signature": "{{project}} टीम",
|
||||
"emails.magicSession.subject": "लॉग इन",
|
||||
"emails.magicSession.hello": "नमस्ते,",
|
||||
"emails.magicSession.body": "इस लिंक के माध्यम से लॉग इन करें।",
|
||||
"emails.magicSession.footer": "यदि आपने इस ईमेल का उपयोग करके लॉगिन करने के लिए नहीं कहा है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.magicSession.body": "इस लिंक के माध्यम से लॉग-इन करें।",
|
||||
"emails.magicSession.footer": "यदि आप इस ईमेल द्वारा लॉगिन नहीं करना चाहते है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.magicSession.thanks": "धन्यवाद",
|
||||
"emails.magicSession.signature": "{{project}} टीम",
|
||||
"emails.recovery.subject": "पासवर्ड रीसेट",
|
||||
"emails.recovery.hello": "नमस्ते {{name}}",
|
||||
"emails.recovery.body": "इस लिंक के माध्यम से अपना {{project}} पासवर्ड रीसेट करें।",
|
||||
"emails.recovery.footer": "यदि आपने अपना पासवर्ड रीसेट करने के लिए नहीं कहा है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.recovery.footer": "यदि आप अपना पासवर्ड रिसेट नहीं करना चाहते है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.recovery.thanks": "धन्यवाद",
|
||||
"emails.recovery.signature": "{{project}} टीम",
|
||||
"emails.invitation.subject": "%s टीम को %s पर आमंत्रण",
|
||||
"emails.invitation.subject": "%s टीम का यहाँ %s पर आमंत्रण",
|
||||
"emails.invitation.hello": "नमस्ते",
|
||||
"emails.invitation.body": "यह मेल आपको इसलिए भेजा गया था क्योंकि {{owner}} आपको {{team}} टीम का सदस्य बनने के लिए आमंत्रित करना चाहते थे जो {{project}} से जुड़ा है।",
|
||||
"emails.invitation.footer": "यदि यह आपके लिए आवश्यक नहीं है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.invitation.body": "यह मेल आपको इसलिए भेजा गया था क्योंकि {{owner}} आपको {{team}} टीम का सदस्य बनाना चाहते थे, जो {{project}} से जुड़ा हुआ है।",
|
||||
"emails.invitation.footer": "यदि आप इसमे रूचि नहीं रखते, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.invitation.thanks": "धन्यवाद",
|
||||
"emails.invitation.signature": "{{project}} टीम",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
"settings.locale": "hu",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Csapat",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Fiók Megerősítése",
|
||||
"emails.verification.hello": "Szia {{name}}",
|
||||
"emails.verification.body": "Kattints a linkre, hogy megerősítsd az email címedet.",
|
||||
"emails.verification.footer": "Ha nem te kérted a címed megerősítését, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
|
||||
"emails.verification.thanks": "Köszönettel",
|
||||
"emails.verification.signature": "a {{project}} csapat",
|
||||
"emails.magicSession.subject": "Bejelentkezés",
|
||||
"emails.magicSession.hello": "Szia,",
|
||||
"emails.magicSession.body": "Kattints a linkre a bejelentkezéshez.",
|
||||
"emails.magicSession.footer": "Ha nem te szerettél volna bejelentkezni ezzel az email címmel, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
|
||||
"emails.magicSession.thanks": "Köszönettel",
|
||||
"emails.magicSession.signature": "a {{project}} csapat",
|
||||
"emails.recovery.subject": "Jelszó Visszaállítása",
|
||||
"emails.recovery.hello": "Hahó, {{name}}",
|
||||
"emails.recovery.body": "Kattints a linkre a {{project}} jelszavad visszaállításához.",
|
||||
"emails.recovery.footer": "Ha nem te kezdeményezted a jelszavad visszaállítását, akkor nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
|
||||
"emails.recovery.thanks": "Köszönettel",
|
||||
"emails.recovery.signature": "a {{project}} csapat",
|
||||
"emails.invitation.subject": "Meghívó a(z) %s csapatba, a(z) %s projektbe",
|
||||
"emails.invitation.hello": "Szia",
|
||||
"emails.invitation.body": "Ezt a levelet azért kaptad, mert {{owner}} meghívott, hogy légy a {{team}} csapat tagja a {{project}} projektben.",
|
||||
"emails.invitation.footer": "Ha nem érdekel a lehetőség, nyugodtan hagyd figyelmen kívül ezt az üzenetet.",
|
||||
"emails.invitation.thanks": "Köszönettel",
|
||||
"emails.invitation.signature": "a {{project}} csapat",
|
||||
"locale.country.unknown": "Ismeretlen",
|
||||
"countries.af": "Afganisztán",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -3,30 +3,30 @@
|
||||
"settings.locale": "jv",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Tim %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "Verifikasi Akun",
|
||||
"emails.verification.hello": "Hai {{name}}",
|
||||
"emails.verification.body": "Klik link iki kanggo verifikasi alamat email sampeyan.",
|
||||
"emails.verification.footer": "Yen sampeyan ora njaluk verifikasi alamat iki, sampeyan iso nglirwakake pesen iki.",
|
||||
"emails.verification.thanks": "Matur nuwun",
|
||||
"emails.verification.signature": "Tim {{project}}",
|
||||
"emails.magicSession.subject": "Masuk",
|
||||
"emails.magicSession.hello": "Hai,",
|
||||
"emails.magicSession.body": "Klik link iki kanggo masuk.",
|
||||
"emails.magicSession.footer": "Yen sampeyan ora njaluk masuk nggunakake alamat email iki, sampeyan iso nglirwakake pesen iki.",
|
||||
"emails.magicSession.thanks": "Matur nuwun",
|
||||
"emails.magicSession.signature": "Tim {{project}}",
|
||||
"emails.recovery.subject": "Setel ulang sandi",
|
||||
"emails.recovery.hello": "Halo {{name}}",
|
||||
"emails.recovery.body": "Klik link iki kanggo setel ulang sandi {{project}}.",
|
||||
"emails.recovery.footer": "Yen sampeyan ora njaluk setel ulang sandi, sampeyan iso nglirwakake pesen iki.",
|
||||
"emails.recovery.thanks": "Matur nuwun",
|
||||
"emails.recovery.signature": "Tim {{project}}",
|
||||
"emails.invitation.subject": "Undangan ke Tim %s di %s",
|
||||
"emails.invitation.hello": "Halo",
|
||||
"emails.invitation.body": "Email iki dikirim menyang sampeyan amarga {{owner}} pengin ngajak sampeyan dadi anggota tim {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Yen sampeyan ora tertarik, sampeyan iso nglirwakake pesen iki.",
|
||||
"emails.invitation.thanks": "Matur nuwun",
|
||||
"emails.invitation.signature": "Tim {{project}}",
|
||||
"locale.country.unknown": "Ora dingerteni",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"Ars sapiendi est ars sciendi quid negligat.\"",
|
||||
"settings.locale": "la",
|
||||
"settings.direction": "ltr*",
|
||||
"emails.sender": "%s team",
|
||||
"emails.verification.subject": "Ratio comprobatio",
|
||||
"emails.verification.hello": "Salve ibi {{name}}",
|
||||
"emails.verification.body": "Sequere hanc nexum ut quin inscriptionem tuum.",
|
||||
"emails.verification.footer": "Si verificationem huius inscriptionis non postulasti, nuntium hunc ignorare potes.",
|
||||
"emails.verification.thanks": "Gratias",
|
||||
"emails.verification.signature": "{{project}} Team",
|
||||
"emails.magicSession.subject": "Log in",
|
||||
"emails.magicSession.hello": "Salve ibi,",
|
||||
"emails.magicSession.body": "Hanc nexum cum login",
|
||||
"emails.magicSession.footer": "Si verificationem huius inscriptionis non postulasti, nuntium hunc ignorare potes.",
|
||||
"emails.magicSession.thanks": "Gratias",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Recuperet password",
|
||||
"emails.recovery.hello": "Salve ibi {{name}}",
|
||||
"emails.recovery.body": "Sequere hanc conjunctionem ut recipias project password {{project}}",
|
||||
"emails.recovery.footer": "Si tesseram tuam recuperare non petis, nuntium hunc ignorare potes",
|
||||
"emails.recovery.thanks": "Gratias",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitatio pro %s in quadrigis %s",
|
||||
"emails.invitation.hello": "Salve ibi",
|
||||
"emails.invitation.body": "Haec inscriptio ad te missa est quia dominus incepto {{owner}} te invitare vult ut membrum {{team}} quadrigis fias ad {{project}}",
|
||||
"emails.invitation.footer": "Si non quaero, potes hunc nuntium ignorare",
|
||||
"emails.invitation.thanks": "Gratias",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Ignotum",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Emiratos Arabes Unidos",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua and Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbaijan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgium",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesh",
|
||||
"countries.bg": "Bulgaria",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnia and Herzegovina",
|
||||
"countries.by": "Belarus",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivia",
|
||||
"countries.br": "Brazil",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Central African Republic",
|
||||
"countries.ca": "Canada",
|
||||
"countries.ch": "Switzerland",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "China",
|
||||
"countries.ci": "Ivory Coast",
|
||||
"countries.cm": "Cameroon",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republic of the Congo",
|
||||
"countries.co": "Colombia",
|
||||
"countries.km": "Comoros",
|
||||
"countries.cv": "Cape Verde",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Cuba",
|
||||
"countries.cy": "Cyprus",
|
||||
"countries.cz": "Czechia",
|
||||
"countries.de": "Germany",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Denmark",
|
||||
"countries.do": "Republica dominicana",
|
||||
"countries.dz": "Algeria",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Egypt",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spain",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Ethiopia",
|
||||
"countries.fi": "Finland",
|
||||
"countries.fj": "Fiji",
|
||||
"countries.fr": "France",
|
||||
"countries.fm": "Micronesia",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Reino Unido",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Equatorial Guinea",
|
||||
"countries.gr": "Greece",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Hungary",
|
||||
"countries.id": "Indonesia",
|
||||
"countries.in": "India",
|
||||
"countries.ie": "Ireland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Iraq",
|
||||
"countries.is": "Iceland",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italy",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kazakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
"countries.kg": "Kyrgyzstan",
|
||||
"countries.kh": "Cambodia",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts and Nevis",
|
||||
"countries.kr": "South Korea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Lebanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libya",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Lithuania",
|
||||
"countries.lu": "Luxembourg",
|
||||
"countries.lv": "Latvia",
|
||||
"countries.ma": "Morocco",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldova",
|
||||
"countries.mg": "Madagascar",
|
||||
"countries.mv": "Maldives",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mh": "Marshall Islands",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambique",
|
||||
"countries.mr": "Mauritania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysia",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Netherlands",
|
||||
"countries.no": "Norway",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "New Zealand",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Philippines",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua New Guinea",
|
||||
"countries.pl": "Poland",
|
||||
"countries.kp": "North Korea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Qatar",
|
||||
"countries.ro": "Romania",
|
||||
"countries.ru": "Russia",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudi Arabia",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapore",
|
||||
"countries.sb": "Solomon Islands",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "South Sudan",
|
||||
"countries.st": "São Tomé and Príncipe",
|
||||
"countries.sr": "Suriname",
|
||||
"countries.sk": "Slovakia",
|
||||
"countries.si": "Slovenia",
|
||||
"countries.se": "Sweden",
|
||||
"countries.sz": "Swaziland",
|
||||
"countries.sc": "Seychelles",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Chad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tajikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad and Tobago",
|
||||
"countries.tn": "Tunisia",
|
||||
"countries.tr": "Turkey",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "United States",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatican City",
|
||||
"countries.vc": "Saint Vincent and the Grenadines",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "Sud-Africa",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Africa",
|
||||
"continents.an": "Antarctica",
|
||||
"continents.as": "Asia",
|
||||
"continents.eu": "Europe",
|
||||
"continents.na": "America del Norte",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "America del Sur"
|
||||
}
|
||||
@@ -3,30 +3,30 @@
|
||||
"settings.locale": "mr",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s टीम",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "खाते सत्यापन",
|
||||
"emails.verification.hello": "नमस्कार {{name}}",
|
||||
"emails.verification.body": "आपला ईमेल पत्ता सत्यापित करण्यासाठी या दुव्याचे अनुसरण करा.",
|
||||
"emails.verification.footer": "आपण या पत्त्याची पडताळणी करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
|
||||
"emails.verification.thanks": "धन्यवाद",
|
||||
"emails.verification.signature": "{{project}} संघ",
|
||||
"emails.magicSession.subject": "लॉगिन करा",
|
||||
"emails.magicSession.hello": "नमस्कार ,",
|
||||
"emails.magicSession.body": "लॉगिन करण्यासाठी या लिंकचे अनुसरण करा.",
|
||||
"emails.magicSession.footer": "आपण या ईमेलचा वापर करून लॉगिन करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
|
||||
"emails.magicSession.thanks": "धन्यवाद",
|
||||
"emails.magicSession.signature": "{{project}} संघ",
|
||||
"emails.recovery.subject": "पासवर्ड रीसेट",
|
||||
"emails.recovery.hello": "नमस्कार {{name}}",
|
||||
"emails.recovery.body": "आपला {{project}}चे पासवर्ड रीसेट करण्यासाठी या लिंकचे अनुसरण करा",
|
||||
"emails.recovery.footer": "आपण आपला पासवर्ड रीसेट करण्यास सांगितले नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
|
||||
"emails.recovery.thanks": "धन्यवाद",
|
||||
"emails.recovery.signature": "{{project}} संघ",
|
||||
"emails.invitation.subject": "%s संघ %s येथे सामील होण्यासाठी आमंत्रण",
|
||||
"emails.invitation.hello": "नमस्कार",
|
||||
"emails.invitation.body": "हा मेल तुम्हाला पाठवला होता कारण {{owner}} तुम्हाला {{project}} येथे {{team}} टीमचे सदस्य होण्यासाठी आमंत्रित करू इच्छित होते.",
|
||||
"emails.invitation.footer": "आपल्याला स्वारस्य नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
|
||||
"emails.invitation.thanks": "धन्यवाद",
|
||||
"emails.invitation.signature": "{{project}} संघ",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
"countries.af": "अफगानिस्तान",
|
||||
"countries.ao": "अंगोला",
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
"settings.inspire": "\"Kunsten å være klok er kunsten å vite hva man skal overse.\"",
|
||||
"settings.locale": "nb",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Teamet",
|
||||
"emails.verification.subject": "Konto Verifisering",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Kontobekreftelse",
|
||||
"emails.verification.hello": "Hei {{name}}",
|
||||
"emails.verification.body": "Følg denne lenken for å verifisere din epost adresse.",
|
||||
"emails.verification.footer": "Hvis du ikke ba om å bekrefte denne adressen, kan du ignorere denne meldingen.",
|
||||
"emails.verification.body": "Følg denne lenken for å bekrefte din e-postadresse.",
|
||||
"emails.verification.footer": "Dersom du ikke ba om å bekrefte e-postadressen, kan du se bort fra denne meldingen.",
|
||||
"emails.verification.thanks": "Takk",
|
||||
"emails.verification.signature": "{{project}} teamet",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Pålogging",
|
||||
"emails.magicSession.hello": "Hei,",
|
||||
"emails.magicSession.body": "Følg denne lenken for å logge inn.",
|
||||
"emails.magicSession.footer": "Hvis du ikke ba om å logge inn med denne adressen, kan du ignorere denne meldingen.",
|
||||
"emails.magicSession.body": "Følg denne lenken for å logge på.",
|
||||
"emails.magicSession.footer": "Dersom du ikke ba om å logge på med denne e-postadressen, kan du se bort fra denne meldingen.",
|
||||
"emails.magicSession.thanks": "Takk",
|
||||
"emails.magicSession.signature": "{{project}} teamet",
|
||||
"emails.recovery.subject": "Reset Passord",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Nullstille passord",
|
||||
"emails.recovery.hello": "Hei {{name}}",
|
||||
"emails.recovery.body": "Følg denne lenken for å resette ditt {{project}} passord.",
|
||||
"emails.recovery.footer": "Hvis du ikke ba om å resette ditt passord, kan du ignorere denne meldingen.",
|
||||
"emails.recovery.body": "Følg denne lenken for å nullstille ditt {{project}} passord.",
|
||||
"emails.recovery.footer": "Dersom du ikke ba om å nullstille passordet ditt, kan du se bort fra denne meldingen.",
|
||||
"emails.recovery.thanks": "Takk",
|
||||
"emails.recovery.signature": "{{project}} teamet",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitasjon til %s Team ved %s",
|
||||
"emails.invitation.hello": "Hei",
|
||||
"emails.invitation.body": "Denne mailen ble sendt til deg fordi {{owner}} hadde lyst til å invitere deg til å bli et medlem av {{team}} teamet ved {{project}}.",
|
||||
"emails.invitation.footer": "Hvis du ikke er interessert, kan du ignorere denne meldingen.",
|
||||
"emails.invitation.body": "Denne meldingen ble sendt til deg fordi {{owner}} ønsket å invitere deg til å bli medlem av {{team}} team ved {{project}}.",
|
||||
"emails.invitation.footer": "Dersom du ikke er interessert, kan du se bort fra denne meldingen.",
|
||||
"emails.invitation.thanks": "Takk",
|
||||
"emails.invitation.signature": "{{project}} teamet",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Ukjent",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
@@ -229,4 +229,4 @@
|
||||
"continents.na": "Nord-Amerika",
|
||||
"continents.oc": "Oseania",
|
||||
"continents.sa": "Sør-Amerika"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
{
|
||||
"settings.inspire": "\"Kunsten å være klok er kunsten å vite hva man skal overse.\"",
|
||||
"settings.locale": "no",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Kontobekreftelse",
|
||||
"emails.verification.hello": "Hallo {{name}}",
|
||||
"emails.verification.body": "Følg denne lenken for å bekrefte din e-postadresse.",
|
||||
"emails.verification.footer": "Dersom du ikke ba om å bekrefte e-postadressen, kan du se bort fra denne meldingen.",
|
||||
"emails.verification.thanks": "Takk",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Pålogging",
|
||||
"emails.magicSession.hello": "Hei,",
|
||||
"emails.magicSession.body": "Følg denne lenken for å logge på.",
|
||||
"emails.magicSession.footer": "Dersom du ikke ba om å logge på med denne e-postadressen, kan du se bort fra denne meldingen.",
|
||||
"emails.magicSession.thanks": "Takk",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Nullstille passord",
|
||||
"emails.recovery.hello": "Hallo {{name}}",
|
||||
"emails.recovery.body": "Følg denne lenken for å nullstille ditt {{project}} passord.",
|
||||
"emails.recovery.footer": "Dersom du ikke ba om å nullstille passordet ditt, kan du se bort fra denne meldingen.",
|
||||
"emails.recovery.thanks": "Takk",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitasjon til %s Team ved %s",
|
||||
"emails.invitation.hello": "Hallo",
|
||||
"emails.invitation.body": "Denne meldingen ble sendt til deg fordi {{owner}} ønsket å invitere deg til å bli medlem av {{team}} team i {{project}}.",
|
||||
"emails.invitation.footer": "Dersom du ikke er interessert, kan du se bort fra denne meldingen.",
|
||||
"emails.invitation.thanks": "Takk",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Ukjent",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "De forente arabiske emirater",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua og Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Østerrike",
|
||||
"countries.az": "Aserbajdsjan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgia",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesh",
|
||||
"countries.bg": "Bulgaria",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnia-Hercegovina",
|
||||
"countries.by": "Hviterussland",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivia",
|
||||
"countries.br": "Brasil",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei Darussalam",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Den sentralafrikanske republikken",
|
||||
"countries.ca": "Canada",
|
||||
"countries.ch": "Sveits",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Kina",
|
||||
"countries.ci": "Elfenbenskysten",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "Den demokratiske republikken Kongo",
|
||||
"countries.cg": "Republikken Kongo",
|
||||
"countries.co": "Colombia",
|
||||
"countries.km": "Komorene",
|
||||
"countries.cv": "Kapp Verde",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Cuba",
|
||||
"countries.cy": "Kypros",
|
||||
"countries.cz": "Tjekkia",
|
||||
"countries.de": "Tyskland",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Danmark",
|
||||
"countries.do": "Den dominikanske republikk",
|
||||
"countries.dz": "Algerie",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Egypt",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spania",
|
||||
"countries.ee": "Estland",
|
||||
"countries.et": "Etiopia",
|
||||
"countries.fi": "Finland",
|
||||
"countries.fj": "Fiji",
|
||||
"countries.fr": "Frankrike",
|
||||
"countries.fm": "Mikronesia",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Storbritannia",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Ekvatorial-Guinea",
|
||||
"countries.gr": "Hellas",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatia",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Ungarn",
|
||||
"countries.id": "Indonesia",
|
||||
"countries.in": "India",
|
||||
"countries.ie": "Irland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italia",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kasakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
"countries.kg": "Kirgisistan",
|
||||
"countries.kh": "Kambodsja",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts og Nevis",
|
||||
"countries.kr": "Sør-Korea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libya",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litauen",
|
||||
"countries.lu": "Luxembourg",
|
||||
"countries.lv": "Latvia",
|
||||
"countries.ma": "Marokko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldova",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldivene",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mh": "Marshalløyene",
|
||||
"countries.mk": "Nord-Makedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauritania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysia",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Nederland",
|
||||
"countries.no": "Norge",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "New Zealand",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filippinene",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Ny-Guinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nord-Korea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Qatar",
|
||||
"countries.ro": "Romania",
|
||||
"countries.ru": "Russland",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudi-Arabia",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapore",
|
||||
"countries.sb": "Solomonøyene",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "Sør-Sudan",
|
||||
"countries.st": "São Tomé og Príncipe",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovakia",
|
||||
"countries.si": "Slovenia",
|
||||
"countries.se": "Sverige",
|
||||
"countries.sz": "Swaziland",
|
||||
"countries.sc": "Seychellene",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Tsjad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tajikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Øst-Timor",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad og Tobago",
|
||||
"countries.tn": "Tunisia",
|
||||
"countries.tr": "Tyrkia",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraina",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "Amerikas forente stater",
|
||||
"countries.uz": "Usbekistan",
|
||||
"countries.va": "Vatikanstaten",
|
||||
"countries.vc": "Saint Vincent og Grenadinene",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Sør-Africa",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktis",
|
||||
"continents.as": "Asia",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Nord-Amerika",
|
||||
"continents.oc": "Oseania",
|
||||
"continents.sa": "Sør-Amerika"
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"Unyanzvi hwekuchenjera kuziva zvekufuratira.\"",
|
||||
"settings.locale": "sn",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Chikwata che%s",
|
||||
"emails.verification.subject": "Kuratidzi kuti ndiwe muridzi weakaundi",
|
||||
"emails.verification.hello": "Hesi {{name}}",
|
||||
"emails.verification.body": "Tevedza chinongedzo ichi kuti uratidze kuti kero iyi ndeyako.",
|
||||
"emails.verification.footer": "Kana usina kukumbira kuti uratidze kuti kero iyi ndeyako, unogona kufuratira meseji iyi.",
|
||||
"emails.verification.thanks": "Ndatenda",
|
||||
"emails.verification.signature": "Chikwata che{{project}}",
|
||||
"emails.magicSession.subject": "Pinda",
|
||||
"emails.magicSession.hello": "Hesi,",
|
||||
"emails.magicSession.body": "Baya chinongedzo ichi kuti upinde muakaundi yako.",
|
||||
"emails.magicSession.footer": "Kana usina kukumbira kupinda muakaundi yako uchishandisa email iyi, unogona kufuratira meseji iyi.",
|
||||
"emails.magicSession.thanks": "Ndatenda",
|
||||
"emails.magicSession.signature": "Chikwata che{{project}}",
|
||||
"emails.recovery.subject": "Kuchinja pasiwedhi",
|
||||
"emails.recovery.hello": "Mhoro {{name}}",
|
||||
"emails.recovery.body": "Baya chinongedzo ichi kuti uchinje pasiwedhi yako ye{{project}}.",
|
||||
"emails.recovery.footer": "Kana usina kukumbira kuchinja pasiwedhi yako, unogona kufuratira meseji iyi.",
|
||||
"emails.recovery.thanks": "Ndatenda",
|
||||
"emails.recovery.signature": "Chikwata che{{project}}",
|
||||
"emails.invitation.subject": "Kukokwa kuchikwata che%s ku%s",
|
||||
"emails.invitation.hello": "Mhoro",
|
||||
"emails.invitation.body": "Tsamba iyi yatumirwa kwauri nekuti {{owner}} anga achida kuti uve nhengo yechikwata che{{team}} pachirongwa che{{project}}.",
|
||||
"emails.invitation.footer": "Kana usiri kufarira kuve nhengo yechikwata ichi, unogona kufuratira meseji iyi.",
|
||||
"emails.invitation.thanks": "Ndatenda",
|
||||
"emails.invitation.signature": "Chikwata che{{project}}",
|
||||
"locale.country.unknown": "Haizivikanwe",
|
||||
"countries.af": "Afuganisitani",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Mubatanidzwa wenyika dzeArab Emirates",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua and Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbaijan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgium",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesh",
|
||||
"countries.bg": "Bulgaria",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnia and Herzegovina",
|
||||
"countries.by": "Belarus",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivia",
|
||||
"countries.br": "Brazil",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Central African Republic",
|
||||
"countries.ca": "Canada",
|
||||
"countries.ch": "Switzerland",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "China",
|
||||
"countries.ci": "Ivory Coast",
|
||||
"countries.cm": "Cameroon",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republic of the Congo",
|
||||
"countries.co": "Colombia",
|
||||
"countries.km": "Comoros",
|
||||
"countries.cv": "Cape Verde",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Cuba",
|
||||
"countries.cy": "Cyprus",
|
||||
"countries.cz": "Czechia",
|
||||
"countries.de": "Germany",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Denmark",
|
||||
"countries.do": "Dominican Republic",
|
||||
"countries.dz": "Algeria",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Egypt",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spain",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Ethiopia",
|
||||
"countries.fi": "Finland",
|
||||
"countries.fj": "Fiji",
|
||||
"countries.fr": "France",
|
||||
"countries.fm": "Micronesia",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "United Kingdom",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Equatorial Guinea",
|
||||
"countries.gr": "Girisi",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Hungary",
|
||||
"countries.id": "Indonesia",
|
||||
"countries.in": "India",
|
||||
"countries.ie": "Ireland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Iraki",
|
||||
"countries.is": "Aisirendi",
|
||||
"countries.il": "Izirayeri",
|
||||
"countries.it": "Itari",
|
||||
"countries.jm": "Jamaika",
|
||||
"countries.jo": "Jodhani",
|
||||
"countries.jp": "Japani",
|
||||
"countries.kz": "Khazakisitani",
|
||||
"countries.ke": "Kenya",
|
||||
"countries.kg": "Kyrgyzstan",
|
||||
"countries.kh": "Kambodhiya",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts and Nevis",
|
||||
"countries.kr": "Koria yekuChamhembe",
|
||||
"countries.kw": "Kuweiti",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Lebanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libya",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Lithuania",
|
||||
"countries.lu": "Luxembourg",
|
||||
"countries.lv": "Latvia",
|
||||
"countries.ma": "Morocco",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldova",
|
||||
"countries.mg": "Madagascar",
|
||||
"countries.mv": "Maldives",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mh": "Marshall Islands",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambiki",
|
||||
"countries.mr": "Moritaniya",
|
||||
"countries.mu": "Morishiyasi",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysia",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Naija",
|
||||
"countries.ng": "Naijeriya",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Netherlands",
|
||||
"countries.no": "Noweyi",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "New Zealand",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakisitani",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Philippines",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua New Guinea",
|
||||
"countries.pl": "Poland",
|
||||
"countries.kp": "North Korea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Qatar",
|
||||
"countries.ro": "Romania",
|
||||
"countries.ru": "Russia",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudi Arabia",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapore",
|
||||
"countries.sb": "Solomon Islands",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "South Sudan",
|
||||
"countries.st": "São Tomé and Príncipe",
|
||||
"countries.sr": "Suriname",
|
||||
"countries.sk": "Slovakia",
|
||||
"countries.si": "Slovenia",
|
||||
"countries.se": "Sweden",
|
||||
"countries.sz": "Swaziland",
|
||||
"countries.sc": "Seychelles",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Chad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tajikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad and Tobago",
|
||||
"countries.tn": "Tunisia",
|
||||
"countries.tr": "Turkey",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "United States",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatican City",
|
||||
"countries.vc": "Saint Vincent and the Grenadines",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "South Africa",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Africa",
|
||||
"continents.an": "Antarctica",
|
||||
"continents.as": "Asia",
|
||||
"continents.eu": "Europe",
|
||||
"continents.na": "North America",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "South America"
|
||||
}
|
||||
@@ -3,30 +3,30 @@
|
||||
"settings.locale": "ta",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s குழு",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "கணக்கு சரிபார்ப்பு",
|
||||
"emails.verification.hello": "ஏய் {{name}}",
|
||||
"emails.verification.body": "உங்கள் மின்னஞ்சல் முகவரியைச் சரிபார்க்க இந்த இணைப்பைப் பின்தொடரவும்.",
|
||||
"emails.verification.footer": "இந்த முகவரியைச் சரிபார்க்கும்படி உங்களிடம் கேட்கப்படவில்லை என்றால், இந்தச் செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
|
||||
"emails.verification.thanks": "நன்றி",
|
||||
"emails.verification.signature": "{{project}} குழு ",
|
||||
"emails.magicSession.subject": "உள்நுழைய",
|
||||
"emails.magicSession.hello": "ஏய்,",
|
||||
"emails.magicSession.body": "இந்த இணைப்பைப் பின்தொடரவும் உள்நுழைய",
|
||||
"emails.magicSession.footer": "இந்த மின்னஞ்சலைப் பயன்படுத்தி உள்நுழையுமாறு உங்களிடம் கேட்கப்படாவிட்டால், இந்தச் செய்தியைப் புறக்கணிக்கலாம்.",
|
||||
"emails.magicSession.thanks": "நன்றி",
|
||||
"emails.magicSession.signature": "{{project}} குழு",
|
||||
"emails.recovery.subject": "கடவுச்சொல் மீட்டமைப்பு",
|
||||
"emails.recovery.hello": "வணக்கம் {{name}}",
|
||||
"emails.recovery.body": "மீட்டமைக்க இந்த இணைப்பைப் பின்தொடரவும் {{project}} கடவுச்சொல்.",
|
||||
"emails.recovery.footer": "உங்கள் கடவுச்சொல்லை மீட்டமைக்கும்படி உங்களிடம் கேட்கப்படவில்லை என்றால், இந்தச் செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
|
||||
"emails.recovery.thanks": "நன்றி",
|
||||
"emails.recovery.signature": "{{project}} குழு",
|
||||
"emails.invitation.subject": "அழைப்பிதழ் %s குழு %s ",
|
||||
"emails.invitation.hello": "வணக்கம்",
|
||||
"emails.invitation.body": "{{project}} இல் {{team}} குழுவில் உறுப்பினராக உங்களை {{owner}} அழைக்க விரும்புவதால், இந்த அஞ்சல் உங்களுக்கு அனுப்பப்பட்டது.",
|
||||
"emails.invitation.footer": "உங்களுக்கு ஆர்வம் இல்லை என்றால், இந்த செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
|
||||
"emails.invitation.thanks": "நன்றி",
|
||||
"emails.invitation.signature": "{{project}} குழு",
|
||||
"locale.country.unknown": "அறியவில்லை",
|
||||
"countries.af": "ஆப்கானித்தான்",
|
||||
"countries.ao": "அங்கோலா",
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"ఏది విస్మరించాలో తెలుసుకోవడమే తెలివైన వ్యక్తి యొక్క కళ.\"",
|
||||
"settings.locale": "te",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s జట్టు",
|
||||
"emails.verification.subject": "ఖాతా ధృవీకరణ",
|
||||
"emails.verification.hello": "నమస్కారము {{name}}",
|
||||
"emails.verification.body": "ఈ లింక్ ద్వారా ఇమెయిల్ ని ధృవీకరించండి",
|
||||
"emails.verification.footer": "మీరు ఈ చిరునామాను ధృవీకరించమని అడగనట్లయితే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు",
|
||||
"emails.verification.thanks": "ధన్యవాదాలు",
|
||||
"emails.verification.signature": "{{project}} జట్",
|
||||
"emails.magicSession.subject": "లాగిన్",
|
||||
"emails.magicSession.hello": "నమస్కారము,",
|
||||
"emails.magicSession.body": "లాగిన్ చేయడానికి ఈ లింక్ ని అనుసరించండి",
|
||||
"emails.magicSession.footer": "మీరు ఈ ఇమెయిల్ ని ఉపయోగించి లాగిన్ చేయమని అడగకపోతే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు",
|
||||
"emails.magicSession.thanks": "ధన్యవాదాలు",
|
||||
"emails.magicSession.signature": "{{project}} జట్",
|
||||
"emails.recovery.subject": "పాస్వర్డ్ రీసెట్",
|
||||
"emails.recovery.hello": "నమస్కారమ {{name}}",
|
||||
"emails.recovery.body": "మీ {{project}} పాస్వర్డ్ ని రీసెట్ చేయడానికి ఈ లింక్ ని అనుసరించండి",
|
||||
"emails.recovery.footer": "మీరు మీ పాస్వర్డ్ ని రీసెట్ చేయమని అడగనట్లయితే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు",
|
||||
"emails.recovery.thanks": "ధన్యవాదాల",
|
||||
"emails.recovery.signature": "{{project}} జట్",
|
||||
"emails.invitation.subject": "%s వద్ద %s బృందానికి ఆహ్వానం",
|
||||
"emails.invitation.hello": "నమస్కారమ",
|
||||
"emails.invitation.body": "{{owner}} మిమ్మల్ని {{project}} లో {{team}} బృందంలో సభ్యునిగా ఉండమని ఆహ్వానించాలనుకుంటున్నందున ఈ మెయిల్ మీకు పంపబడింది.",
|
||||
"emails.invitation.footer": "మీకు ఆసక్తి లేకుంటే, మీరు ఈ సందేశాన్ని విస్మరించవచ్చు.",
|
||||
"emails.invitation.thanks": "ధన్యవాదాల",
|
||||
"emails.invitation.signature": "{{project}} జట్",
|
||||
"locale.country.unknown": "తెలియని",
|
||||
"countries.af": "ఆఫ్ఘనిస్తాన్",
|
||||
"countries.ao": "అంగోలా",
|
||||
"countries.al": "అల్బేనియా",
|
||||
"countries.ad": "అండోరా",
|
||||
"countries.ae": "యునైటెడ్ అరబ్ ఎమిరేట్స్",
|
||||
"countries.ar": "అర్జెంటీనా",
|
||||
"countries.am": "అర్మేనియా",
|
||||
"countries.ag": "ఆంటిగ్వా మరియు బార్బుడా",
|
||||
"countries.au": "ఆస్ట్రేలియా",
|
||||
"countries.at": "ఆస్ట్రియా",
|
||||
"countries.az": "అజర్బైజాన్",
|
||||
"countries.bi": "బురుండి",
|
||||
"countries.be": "బెల్జియం",
|
||||
"countries.bj": "బెనిన్",
|
||||
"countries.bf": "బుర్కినా ఫాసో",
|
||||
"countries.bd": "బంగ్లాదేశ్",
|
||||
"countries.bg": "బల్గేరియా",
|
||||
"countries.bh": "బహ్రెయిన్",
|
||||
"countries.bs": "బహామాస్",
|
||||
"countries.ba": "బోస్నియా మరియు హెర్జెగోవినా",
|
||||
"countries.by": "బెలారస్",
|
||||
"countries.bz": "బెలీజ్",
|
||||
"countries.bo": "బొలీవియా",
|
||||
"countries.br": "బ్రెజిల్",
|
||||
"countries.bb": "బార్బడోస్",
|
||||
"countries.bn": "బ్రూనై",
|
||||
"countries.bt": "భూటాన్",
|
||||
"countries.bw": "బోట్స్వానా",
|
||||
"countries.cf": "సెంట్రల్ ఆఫ్రికన్ రిపబ్లిక్",
|
||||
"countries.ca": "కెనడా",
|
||||
"countries.ch": "స్విట్జర్లాండ్",
|
||||
"countries.cl": "చిలీ",
|
||||
"countries.cn": "చైనా",
|
||||
"countries.ci": "ఐవరీ కోస్ట్",
|
||||
"countries.cm": "కామెరూన్",
|
||||
"countries.cd": "DR కాంగో",
|
||||
"countries.cg": "రిపబ్లిక్ ఆఫ్ కాంగో",
|
||||
"countries.co": "కొలంబియా",
|
||||
"countries.km": "కొమోరోస్",
|
||||
"countries.cv": "కేప్ వర్దె",
|
||||
"countries.cr": "కోస్టా రికా",
|
||||
"countries.cu": "క్యూబా",
|
||||
"countries.cy": "సైప్రస్",
|
||||
"countries.cz": "చెకియా",
|
||||
"countries.de": "జర్మనీ",
|
||||
"countries.dj": "జిబౌటీ",
|
||||
"countries.dm": "డొమినికా",
|
||||
"countries.dk": "డెన్మార్క్",
|
||||
"countries.do": "డొమినికన్ రిపబ్లిక్",
|
||||
"countries.dz": "అల్జీరియా",
|
||||
"countries.ec": "ఈక్వెడార్",
|
||||
"countries.eg": "ఈజిప్ట్",
|
||||
"countries.er": "ఎరిత్రియా",
|
||||
"countries.es": "స్పెయిన్",
|
||||
"countries.ee": "ఎస్టోనియా",
|
||||
"countries.et": "ఇథియోపియా",
|
||||
"countries.fi": "ఫిన్లాండ్",
|
||||
"countries.fj": "ఫిజీ",
|
||||
"countries.fr": "ఫ్రాన్స్",
|
||||
"countries.fm": "మైక్రోనేషియా",
|
||||
"countries.ga": "గాబోన్",
|
||||
"countries.gb": "యునైటెడ్ కింగ్డమ్",
|
||||
"countries.ge": "జార్జియా",
|
||||
"countries.gh": "ఘానా",
|
||||
"countries.gn": "గినియా",
|
||||
"countries.gm": "గాంబియా",
|
||||
"countries.gw": "గిన్-బిస్సౌ",
|
||||
"countries.gq": "ఈక్వటోరియల్ గిన్",
|
||||
"countries.gr": "గ్రీస్",
|
||||
"countries.gd": "గ్రెనడా",
|
||||
"countries.gt": "గ్వాటెమాల",
|
||||
"countries.gy": "గయానా",
|
||||
"countries.hn": "హోండురాస్",
|
||||
"countries.hr": "క్రొయేషియా",
|
||||
"countries.ht": "హైతీ",
|
||||
"countries.hu": "హంగేరి",
|
||||
"countries.id": "ఇండోనేషియా",
|
||||
"countries.in": "భారతదేశం",
|
||||
"countries.ie": "ఐర్లాండ్",
|
||||
"countries.ir": "ఇరాన్",
|
||||
"countries.iq": "ఇరాక్",
|
||||
"countries.is": "ఐస్లాండ్",
|
||||
"countries.il": "ఇజ్రాయెల్",
|
||||
"countries.it": "ఇటలీ",
|
||||
"countries.jm": "జమైకా",
|
||||
"countries.jo": "జోర్డాన్",
|
||||
"countries.jp": "జపాన్",
|
||||
"countries.kz": "కజకిస్తాన్",
|
||||
"countries.ke": "కెన్యా",
|
||||
"countries.kg": "కిర్గిజ్స్తాన్",
|
||||
"countries.kh": "కంబోడియా",
|
||||
"countries.ki": "కిరిబాటి",
|
||||
"countries.kn": "సెయింట్ కిట్స్ అండ్ నెవిస్",
|
||||
"countries.kr": "దక్షిణ కొరియా",
|
||||
"countries.kw": "కువైట్",
|
||||
"countries.la": "లావోస్",
|
||||
"countries.lb": "లెబనాన్",
|
||||
"countries.lr": "లైబీరియా",
|
||||
"countries.ly": "లిబియా",
|
||||
"countries.lc": "సెయింట్ లూసియా",
|
||||
"countries.li": "లీచ్టెన్స్టెయిన్",
|
||||
"countries.lk": "శ్రీలంక",
|
||||
"countries.ls": "లెసోతో",
|
||||
"countries.lt": "లిథువేనియా",
|
||||
"countries.lu": "లక్సెంబర్గ్",
|
||||
"countries.lv": "లాట్వియా",
|
||||
"countries.ma": "మొరాకో",
|
||||
"countries.mc": "మొనాకో",
|
||||
"countries.md": "మోల్డోవా",
|
||||
"countries.mg": "మడగాస్కర్",
|
||||
"countries.mv": "మాల్దీవులు",
|
||||
"countries.mx": "మెక్సికో",
|
||||
"countries.mh": "మార్షల్ దీవులు",
|
||||
"countries.mk": "మాసిడోనియా",
|
||||
"countries.ml": "మాలి",
|
||||
"countries.mt": "మాల్టా",
|
||||
"countries.mm": "మయన్మార్",
|
||||
"countries.me": "మాంటెనెగ్రో",
|
||||
"countries.mn": "మంగోలియా",
|
||||
"countries.mz": "మొజాంబిక్",
|
||||
"countries.mr": "మౌరిటానియా",
|
||||
"countries.mu": "మారిషస్",
|
||||
"countries.mw": "మలావి",
|
||||
"countries.my": "మలేషియా",
|
||||
"countries.na": "నమీబియా",
|
||||
"countries.ne": "నైజర్",
|
||||
"countries.ng": "నైజీరియా",
|
||||
"countries.ni": "నికరాగ్వా",
|
||||
"countries.nl": "నెదర్లాండ్స్",
|
||||
"countries.no": "నార్వే",
|
||||
"countries.np": "నేపాల్",
|
||||
"countries.nr": "నౌరు",
|
||||
"countries.nz": "న్యూజిలాండ్",
|
||||
"countries.om": "ఒమన్",
|
||||
"countries.pk": "పాకిస్తాన్",
|
||||
"countries.pa": "పనామా",
|
||||
"countries.pe": "పెరూ",
|
||||
"countries.ph": "ఫిలిప్పీన్స్",
|
||||
"countries.pw": "పలావ్",
|
||||
"countries.pg": "పాపువా న్యూ గిన్",
|
||||
"countries.pl": "పోలాండ్",
|
||||
"countries.kp": "ఉత్తర కొరియా",
|
||||
"countries.pt": "పోర్చుగల్",
|
||||
"countries.py": "పరాగ్వే",
|
||||
"countries.qa": "ఖతార్",
|
||||
"countries.ro": "రొమేనియా",
|
||||
"countries.ru": "రష్యా",
|
||||
"countries.rw": "రువాండా",
|
||||
"countries.sa": "సౌదీ అరేబియా",
|
||||
"countries.sd": "సూడాన్",
|
||||
"countries.sn": "సెనెగల్",
|
||||
"countries.sg": "సింగపూర్",
|
||||
"countries.sb": "సోలమన్ దీవులు",
|
||||
"countries.sl": "సియెర్రా లియోన్",
|
||||
"countries.sv": "ఎల్ సాల్వడార్",
|
||||
"countries.sm": "శాన్ మారినో",
|
||||
"countries.so": "సోమాలియా",
|
||||
"countries.rs": "సెర్బియా",
|
||||
"countries.ss": "దక్షిణ సూడాన్",
|
||||
"countries.st": "సావో టోమ్ మరియు ప్రిన్సిపే",
|
||||
"countries.sr": "సురినామ్",
|
||||
"countries.sk": "స్లోవేకియా",
|
||||
"countries.si": "స్లోవేనియా",
|
||||
"countries.se": "స్వీడన్",
|
||||
"countries.sz": "స్వాజిలాండ్",
|
||||
"countries.sc": "సీషెల్స్",
|
||||
"countries.sy": "సిరియా",
|
||||
"countries.td": "చాడ్",
|
||||
"countries.tg": "టోగో",
|
||||
"countries.th": "థాయిలాండ్",
|
||||
"countries.tj": "తజికిస్తాన్",
|
||||
"countries.tm": "తుర్క్మెనిస్తాన్",
|
||||
"countries.tl": "తైమోర్-లెస్టే",
|
||||
"countries.to": "టాంగా",
|
||||
"countries.tt": "ట్రినిడాడ్ మరియు టొబాగో",
|
||||
"countries.tn": "ట్యునీషియా",
|
||||
"countries.tr": "టర్కీ",
|
||||
"countries.tv": "తువాలు",
|
||||
"countries.tz": "టాంజానియా",
|
||||
"countries.ug": "ఉగాండా",
|
||||
"countries.ua": "ఉక్రెయిన్",
|
||||
"countries.uy": "ఉరుగ్వే",
|
||||
"countries.us": "యునైటెడ్ స్టేట్స్",
|
||||
"countries.uz": "ఉజ్బెకిస్తాన్",
|
||||
"countries.va": "వాటికన్ నగరం",
|
||||
"countries.vc": "సెయింట్ విన్సెంట్ మరియు గ్రెనడిన్స్",
|
||||
"countries.ve": "వెనిజులా",
|
||||
"countries.vn": "వియత్నాం",
|
||||
"countries.vu": "వనాటు",
|
||||
"countries.ws": "సమోవా",
|
||||
"countries.ye": "యెమెన్",
|
||||
"countries.za": "దక్షిణాఫ్రికా",
|
||||
"countries.zm": "జాంబియా",
|
||||
"countries.zw": "జింబాబ్వే",
|
||||
"continents.af": "ఆఫ్రికా",
|
||||
"continents.an": "అంటార్కిటికా",
|
||||
"continents.as": "ఆసియా",
|
||||
"continents.eu": "యూరోప్",
|
||||
"continents.na": "ఉత్తర అమెరికా",
|
||||
"continents.oc": "ఓషియానియా",
|
||||
"continents.sa": "దక్షిణ అమెరికా"
|
||||
}
|
||||
@@ -3,30 +3,30 @@
|
||||
"settings.locale": "ur",
|
||||
"settings.direction": "rtl",
|
||||
"emails.sender": "%s ٹیم",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.signature": "",
|
||||
"emails.magicSession.subject": "",
|
||||
"emails.magicSession.hello": "",
|
||||
"emails.magicSession.body": "",
|
||||
"emails.magicSession.footer": "",
|
||||
"emails.magicSession.thanks": "",
|
||||
"emails.magicSession.signature": "",
|
||||
"emails.recovery.subject": "",
|
||||
"emails.recovery.hello": "",
|
||||
"emails.recovery.body": "",
|
||||
"emails.recovery.footer": "",
|
||||
"emails.recovery.thanks": "",
|
||||
"emails.recovery.signature": "",
|
||||
"emails.invitation.subject": "",
|
||||
"emails.invitation.hello": "",
|
||||
"emails.invitation.body": "",
|
||||
"emails.invitation.footer": "",
|
||||
"emails.invitation.thanks": "",
|
||||
"emails.invitation.signature": "",
|
||||
"emails.verification.subject": "اکاؤنٹ کی تصدیق",
|
||||
"emails.verification.hello": "خوش آمدید {{name}}",
|
||||
"emails.verification.body": "براہ کرم اپنے ای میل کی تصدیق کے لیے درج ذیل لنک پر عمل کریں۔",
|
||||
"emails.verification.footer": "اگر آپ نے اس پتے کی تصدیق کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
|
||||
"emails.verification.thanks": "شکریہ",
|
||||
"emails.verification.signature": "ٹیم۔ {{project}}",
|
||||
"emails.magicSession.subject": "اگ ان کریں",
|
||||
"emails.magicSession.hello": "خوش آمدید,",
|
||||
"emails.magicSession.body": "لاگ ان کرنے کے لیے اس لنک پر عمل کریں۔",
|
||||
"emails.magicSession.footer": "اگر آپ نے اس ای میل کا استعمال کرتے ہوئے لاگ ان کرنے کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
|
||||
"emails.magicSession.thanks": "شکریہ",
|
||||
"emails.magicSession.signature": "ٹیم۔ {{project}}",
|
||||
"emails.recovery.subject": "پاس ورڈ ری سیٹ۔",
|
||||
"emails.recovery.hello": "ہیلو {{name}}",
|
||||
"emails.recovery.body": "{{project}} کا پاس ورڈ تبدیل کرنے کے لیے درج ذیل لنک پر عمل کریں",
|
||||
"emails.recovery.footer": "اگر آپ نے اپنا پاس ورڈ دوبارہ ترتیب دینے کے لیے نہیں کہا تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
|
||||
"emails.recovery.thanks": "شکریہ",
|
||||
"emails.recovery.signature": "ٹیم۔ {{project}}",
|
||||
"emails.invitation.subject": "%s پر %s ٹیم کو دعوت",
|
||||
"emails.invitation.hello": "خوش آمدید",
|
||||
"emails.invitation.body": "یہ پیغام آپ کو اس لیے بھیجا گیا تھا کہ {{owner}} نے آپ کو {{project}} میں {{team}} ٹیم کا رکن بننے کی دعوت بھیجی",
|
||||
"emails.invitation.footer": "اگر آپ دلچسپی نہیں رکھتے تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
|
||||
"emails.invitation.thanks": "شکریہ",
|
||||
"emails.invitation.signature": "ٹیم۔ {{project}",
|
||||
"locale.country.unknown": "نامعلوم",
|
||||
"countries.af": "افغانستان",
|
||||
"countries.ao": "انگولا",
|
||||
@@ -229,4 +229,4 @@
|
||||
"continents.na": "شمالی امریکہ",
|
||||
"continents.oc": "اوشینیا",
|
||||
"continents.sa": "جنوبی امریکہ"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ return [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '4.0.4',
|
||||
'version' => '7.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -63,7 +63,7 @@ return [
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '2.0.3',
|
||||
'version' => '4.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -81,7 +81,7 @@ return [
|
||||
[
|
||||
'key' => 'apple',
|
||||
'name' => 'Apple',
|
||||
'version' => '0.1.1',
|
||||
'version' => '0.3.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'enabled' => true,
|
||||
@@ -116,7 +116,7 @@ return [
|
||||
[
|
||||
'key' => 'android',
|
||||
'name' => 'Android',
|
||||
'version' => '0.2.1',
|
||||
'version' => '0.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-android',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android',
|
||||
'enabled' => true,
|
||||
@@ -152,17 +152,17 @@ return [
|
||||
// ],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
APP_PLATFORM_CONSOLE => [
|
||||
'key' => APP_PLATFORM_CONSOLE,
|
||||
'name' => 'Console',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
'languages' => [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Console',
|
||||
'version' => '4.0.4',
|
||||
'version' => '5.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-console',
|
||||
'package' => '',
|
||||
'enabled' => true,
|
||||
@@ -177,6 +177,24 @@ return [
|
||||
'gitRepoName' => 'sdk-for-console',
|
||||
'gitUserName' => 'appwrite',
|
||||
],
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '0.15.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_CONSOLE,
|
||||
'prism' => 'bash',
|
||||
'source' => \realpath(__DIR__ . '/../sdks/console-cli'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-cli.git',
|
||||
'gitRepoName' => 'sdk-for-cli',
|
||||
'gitUserName' => 'appwrite',
|
||||
'gitBranch' => 'main',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
@@ -186,11 +204,11 @@ return [
|
||||
'description' => 'Libraries for integrating with Appwrite to build server side integrations. Read the [getting started for server](/docs/getting-started-for-server) tutorial to start building your first server integration.',
|
||||
'enabled' => true,
|
||||
'beta' => false,
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
'languages' => [
|
||||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '2.5.1',
|
||||
'version' => '5.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -208,11 +226,11 @@ return [
|
||||
[
|
||||
'key' => 'deno',
|
||||
'name' => 'Deno',
|
||||
'version' => '0.4.1',
|
||||
'version' => '3.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-deno',
|
||||
'package' => 'https://deno.land/x/appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'beta' => false,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
@@ -226,7 +244,7 @@ return [
|
||||
[
|
||||
'key' => 'php',
|
||||
'name' => 'PHP',
|
||||
'version' => '2.3.2',
|
||||
'version' => '4.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-php',
|
||||
'package' => 'https://packagist.org/packages/appwrite/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -244,7 +262,7 @@ return [
|
||||
[
|
||||
'key' => 'python',
|
||||
'name' => 'Python',
|
||||
'version' => '0.5.1',
|
||||
'version' => '0.7.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-python',
|
||||
'package' => 'https://pypi.org/project/appwrite/',
|
||||
'enabled' => true,
|
||||
@@ -262,7 +280,7 @@ return [
|
||||
[
|
||||
'key' => 'ruby',
|
||||
'name' => 'Ruby',
|
||||
'version' => '2.4.1',
|
||||
'version' => '4.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-ruby',
|
||||
'package' => 'https://rubygems.org/gems/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -316,7 +334,7 @@ return [
|
||||
[
|
||||
'key' => 'dotnet',
|
||||
'name' => '.NET',
|
||||
'version' => '0.3.0',
|
||||
'version' => '0.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
|
||||
'package' => 'https://www.nuget.org/packages/Appwrite',
|
||||
'enabled' => false,
|
||||
@@ -334,7 +352,7 @@ return [
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '1.0.2',
|
||||
'version' => '4.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
@@ -349,28 +367,10 @@ return [
|
||||
'gitUserName' => 'appwrite',
|
||||
'gitBranch' => 'master',
|
||||
],
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '0.12.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'dev' => false,
|
||||
'hidden' => true,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
'prism' => 'bash',
|
||||
'source' => \realpath(__DIR__ . '/../sdks/server-cli'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-cli.git',
|
||||
'gitRepoName' => 'sdk-for-cli',
|
||||
'gitUserName' => 'appwrite',
|
||||
'gitBranch' => 'master',
|
||||
],
|
||||
[
|
||||
'key' => 'kotlin',
|
||||
'name' => 'Kotlin',
|
||||
'version' => '0.1.1',
|
||||
'version' => '0.3.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
|
||||
'enabled' => true,
|
||||
@@ -392,7 +392,7 @@ return [
|
||||
[
|
||||
'key' => 'swift',
|
||||
'name' => 'Swift',
|
||||
'version' => '0.1.0',
|
||||
'version' => '0.3.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'enabled' => true,
|
||||
|
||||
@@ -84,7 +84,7 @@ return [ // Ordered by ABC.
|
||||
'github' => [
|
||||
'name' => 'GitHub',
|
||||
'developers' => 'https://developer.github.com/',
|
||||
'icon' => 'icon-github-circled',
|
||||
'icon' => 'icon-github',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => false,
|
||||
@@ -127,6 +127,16 @@ return [ // Ordered by ABC.
|
||||
'icon' => 'icon-windows',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => 'microsoft.phtml',
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'notion' => [
|
||||
'name' => 'Notion',
|
||||
'developers' => 'https://developers.notion.com/docs',
|
||||
'icon' => 'icon-notion',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => false,
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
@@ -221,6 +231,16 @@ return [ // Ordered by ABC.
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'zoom' => [
|
||||
'name' => 'Zoom',
|
||||
'developers' => 'https://marketplace.zoom.us/docs/guides/auth/oauth/',
|
||||
'icon' => 'icon-zoom',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => false,
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'yahoo' => [
|
||||
'name' => 'Yahoo',
|
||||
'developers' => 'https://developer.yahoo.com/oauth2/guide/flows_authcode/',
|
||||
@@ -231,6 +251,16 @@ return [ // Ordered by ABC.
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'yammer' => [
|
||||
'name' => 'Yammer',
|
||||
'developers' => 'https://developer.yammer.com/docs/oauth-2',
|
||||
'icon' => 'icon-yammer',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => false,
|
||||
'beta' => false,
|
||||
'mock' => false,
|
||||
],
|
||||
'yandex' => [
|
||||
'name' => 'Yandex',
|
||||
'developers' => 'https://tech.yandex.com/oauth/',
|
||||
@@ -267,6 +297,16 @@ return [ // Ordered by ABC.
|
||||
'beta' => false,
|
||||
'mock' => false
|
||||
],
|
||||
'stripe' => [
|
||||
'name' => 'Stripe',
|
||||
'developers' => 'https://stripe.com/docs/api',
|
||||
'icon' => 'icon-stripe',
|
||||
'enabled' => true,
|
||||
'sandbox' => false,
|
||||
'form' => false,
|
||||
'beta' => false,
|
||||
'mock' => false
|
||||
],
|
||||
// Keep Last
|
||||
'mock' => [
|
||||
'name' => 'Mock',
|
||||
|
||||
@@ -30,6 +30,8 @@ $admins = [
|
||||
'documents.write',
|
||||
'files.read',
|
||||
'files.write',
|
||||
'buckets.read',
|
||||
'buckets.write',
|
||||
'users.read',
|
||||
'users.write',
|
||||
'collections.read',
|
||||
@@ -38,8 +40,6 @@ $admins = [
|
||||
'platforms.write',
|
||||
'keys.read',
|
||||
'keys.write',
|
||||
'tasks.read',
|
||||
'tasks.write',
|
||||
'webhooks.read',
|
||||
'webhooks.write',
|
||||
'locale.read',
|
||||
|
||||
@@ -19,6 +19,18 @@ return [ // List of publicly visible scopes
|
||||
'collections.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s database collections',
|
||||
],
|
||||
'attributes.read' => [
|
||||
'description' => 'Access to read your project\'s database collection\'s attributes',
|
||||
],
|
||||
'attributes.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s database collection\'s attributes',
|
||||
],
|
||||
'indexes.read' => [
|
||||
'description' => 'Access to read your project\'s database collection\'s indexes',
|
||||
],
|
||||
'indexes.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s database collection\'s indexes',
|
||||
],
|
||||
'documents.read' => [
|
||||
'description' => 'Access to read your project\'s database documents',
|
||||
],
|
||||
@@ -31,11 +43,17 @@ return [ // List of publicly visible scopes
|
||||
'files.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s storage files',
|
||||
],
|
||||
'buckets.read' => [
|
||||
'description' => 'Access to read your project\'s storage buckets',
|
||||
],
|
||||
'buckets.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s storage buckets',
|
||||
],
|
||||
'functions.read' => [
|
||||
'description' => 'Access to read your project\'s functions and code tags',
|
||||
'description' => 'Access to read your project\'s functions and code deployments',
|
||||
],
|
||||
'functions.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s functions and code tags',
|
||||
'description' => 'Access to create, update, and delete your project\'s functions and code deployments',
|
||||
],
|
||||
'execution.read' => [
|
||||
'description' => 'Access to read your project\'s execution logs',
|
||||
|
||||
@@ -5,20 +5,29 @@ return [
|
||||
'key' => 'homepage',
|
||||
'name' => 'Homepage',
|
||||
'subtitle' => '',
|
||||
'description' => '',
|
||||
'controller' => 'web/home.php',
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
'docsUrl' => '',
|
||||
'tests' => false,
|
||||
'optional' => false,
|
||||
'icon' => '',
|
||||
],
|
||||
'console/' => [
|
||||
'console' => [
|
||||
'key' => 'console',
|
||||
'name' => 'Console',
|
||||
'subtitle' => '',
|
||||
'description' => '',
|
||||
'controller' => 'web/console.php',
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
'docsUrl' => '',
|
||||
'tests' => false,
|
||||
'optional' => false,
|
||||
'icon' => '',
|
||||
],
|
||||
'v1/account' => [
|
||||
'account' => [
|
||||
'key' => 'account',
|
||||
'name' => 'Account',
|
||||
'subtitle' => 'The Account service allows you to authenticate and manage a user account.',
|
||||
@@ -26,9 +35,12 @@ return [
|
||||
'controller' => 'api/account.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/account',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/account.png',
|
||||
],
|
||||
'v1/avatars' => [
|
||||
'avatars' => [
|
||||
'key' => 'avatars',
|
||||
'name' => 'Avatars',
|
||||
'subtitle'=> 'The Avatars service aims to help you complete everyday tasks related to your app image, icons, and avatars.',
|
||||
@@ -36,9 +48,12 @@ return [
|
||||
'controller' => 'api/avatars.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/avatars',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/avatars.png',
|
||||
],
|
||||
'v1/database' => [
|
||||
'database' => [
|
||||
'key' => 'database',
|
||||
'name' => 'Database',
|
||||
'subtitle' => 'The Database service allows you to create structured collections of documents, query and filter lists of documents',
|
||||
@@ -46,9 +61,12 @@ return [
|
||||
'controller' => 'api/database.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/database',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/database.png',
|
||||
],
|
||||
'v1/locale' => [
|
||||
'locale' => [
|
||||
'key' => 'locale',
|
||||
'name' => 'Locale',
|
||||
'subtitle' => 'The Locale service allows you to customize your app based on your users\' location.',
|
||||
@@ -56,9 +74,12 @@ return [
|
||||
'controller' => 'api/locale.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/locale',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/locale.png',
|
||||
],
|
||||
'v1/health' => [
|
||||
'health' => [
|
||||
'key' => 'health',
|
||||
'name' => 'Health',
|
||||
'subtitle' => 'The Health service allows you to both validate and monitor your Appwrite server\'s health.',
|
||||
@@ -66,18 +87,25 @@ return [
|
||||
'controller' => 'api/health.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/server/health',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/health.png',
|
||||
],
|
||||
'v1/projects' => [
|
||||
'projects' => [
|
||||
'key' => 'projects',
|
||||
'name' => 'Projects',
|
||||
'subtitle' => 'The Project service allows you to manage all the projects in your Appwrite server.',
|
||||
'description' => '',
|
||||
'controller' => 'api/projects.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => '',
|
||||
'tests' => false,
|
||||
'optional' => false,
|
||||
'icon' => '',
|
||||
],
|
||||
'v1/storage' => [
|
||||
'storage' => [
|
||||
'key' => 'storage',
|
||||
'name' => 'Storage',
|
||||
'subtitle' => 'The Storage service allows you to manage your project files.',
|
||||
@@ -85,9 +113,12 @@ return [
|
||||
'controller' => 'api/storage.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/storage',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/storage.png',
|
||||
],
|
||||
'v1/teams' => [
|
||||
'teams' => [
|
||||
'key' => 'teams',
|
||||
'name' => 'Teams',
|
||||
'subtitle' => 'The Teams service allows you to group users of your project and to enable them to share read and write access to your project resources',
|
||||
@@ -95,9 +126,12 @@ return [
|
||||
'controller' => 'api/teams.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/teams',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/teams.png',
|
||||
],
|
||||
'v1/users' => [
|
||||
'users' => [
|
||||
'key' => 'users',
|
||||
'name' => 'Users',
|
||||
'subtitle' => 'The Users service allows you to manage your project users.',
|
||||
@@ -105,9 +139,12 @@ return [
|
||||
'controller' => 'api/users.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/server/users',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/users.png',
|
||||
],
|
||||
'v1/functions' => [
|
||||
'functions' => [
|
||||
'key' => 'functions',
|
||||
'name' => 'Functions',
|
||||
'subtitle' => 'The Functions Service allows you view, create and manage your Cloud Functions.',
|
||||
@@ -115,9 +152,12 @@ return [
|
||||
'controller' => 'api/functions.php',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/functions',
|
||||
'tests' => false,
|
||||
'optional' => true,
|
||||
'icon' => '/images/services/functions.png',
|
||||
],
|
||||
'v1/mock' => [
|
||||
'mock' => [
|
||||
'key' => 'mock',
|
||||
'name' => 'Mock',
|
||||
'subtitle' => '',
|
||||
@@ -125,9 +165,12 @@ return [
|
||||
'controller' => 'mock.php',
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
'docsUrl' => '',
|
||||
'tests' => true,
|
||||
'optional' => false,
|
||||
'icon' => '',
|
||||
],
|
||||
'v1/graphql' => [
|
||||
'graphql' => [
|
||||
'key' => 'graphql',
|
||||
'name' => 'GraphQL',
|
||||
'subtitle' => 'Appwrite\'s GraphQL Endpoint',
|
||||
@@ -135,6 +178,9 @@ return [
|
||||
'controller' => 'api/graphql.php',
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
'tests' => false,
|
||||
'docsUrl' => '',
|
||||
'tests' => true,
|
||||
'optional' => false,
|
||||
'icon' => '',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
return [ // Based on this list @see http://stackoverflow.com/a/4212908/2299554
|
||||
'default' => __DIR__.'/logos/none.png',
|
||||
'default_image' => __DIR__.'/logos/image.png',
|
||||
|
||||
// Video Files
|
||||
'video/mp4' => __DIR__.'/logos/video.png',
|
||||
@@ -14,30 +15,30 @@ return [ // Based on this list @see http://stackoverflow.com/a/4212908/2299554
|
||||
'video/x-ms-wmv' => __DIR__.'/logos/video.png',
|
||||
|
||||
// // Microsoft Word
|
||||
'application/msword' => __DIR__.'/logos/word.png',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => __DIR__.'/logos/word.png',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => __DIR__.'/logos/word.png',
|
||||
'application/vnd.ms-word.document.macroEnabled.12' => __DIR__.'/logos/word.png',
|
||||
// 'application/msword' => __DIR__.'/logos/word.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => __DIR__.'/logos/word.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => __DIR__.'/logos/word.png',
|
||||
// 'application/vnd.ms-word.document.macroEnabled.12' => __DIR__.'/logos/word.png',
|
||||
|
||||
// // Microsoft Excel
|
||||
'application/vnd.ms-excel' => __DIR__.'/logos/excel.png',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => __DIR__.'/logos/excel.png',
|
||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => __DIR__.'/logos/excel.png',
|
||||
'application/vnd.ms-excel.sheet.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
'application/vnd.ms-excel.template.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
'application/vnd.ms-excel.addin.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.ms-excel' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.ms-excel.sheet.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.ms-excel.template.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.ms-excel.addin.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
// 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => __DIR__.'/logos/excel.png',
|
||||
|
||||
// // Microsoft Power Point
|
||||
'application/vnd.ms-powerpoint' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.template' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.ms-powerpoint.addin.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.ms-powerpoint.template.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.ms-powerpoint' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.presentationml.template' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.ms-powerpoint.addin.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.ms-powerpoint.template.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
// 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => __DIR__.'/logos/ppt.png',
|
||||
|
||||
// Adobe PDF
|
||||
'application/pdf' => __DIR__.'/logos/pdf.png',
|
||||
// 'application/pdf' => __DIR__.'/logos/pdf.png',
|
||||
];
|
||||
|
Before Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 12 KiB |
@@ -72,7 +72,7 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => '_APP_CONSOLE_WHITELIST_ROOT',
|
||||
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by invting them to your project. By default this option is enabled.',
|
||||
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by inviting them to your project. By default this option is enabled.',
|
||||
'introduction' => '0.8.0',
|
||||
'default' => 'enabled',
|
||||
'required' => false,
|
||||
@@ -149,6 +149,42 @@ return [
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_LOGGING_PROVIDER',
|
||||
'description' => 'This variable allows you to enable logging errors to 3rd party providers. This value is empty by default, to enable the logger set the value to one of \'sentry\', \'raygun\', \'appsignal\', \'logowl\'',
|
||||
'introduction' => '0.12.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_LOGGING_CONFIG',
|
||||
'description' => 'This variable configures authentication to 3rd party error logging providers. If using Sentry, this should be \'SENTRY_API_KEY;SENTRY_APP_ID\'. If using Raygun, this should be Raygun API key. If using AppSignal, this should be AppSignal API key. If using LogOwl, this should be LogOwl Service Ticket.',
|
||||
'introduction' => '0.12.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_USAGE_AGGREGATION_INTERVAL',
|
||||
'description' => 'Interval value containing the number of seconds that the Appwrite usage process should wait before aggregating stats and syncing it to mariadb from InfluxDB. The default value is 30 seconds.',
|
||||
'introduction' => '0.10.0',
|
||||
'default' => '30',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_WORKER_PER_CORE',
|
||||
'description' => 'Internal Worker per core for the API, Realtime and Executor containers. Can be configured to optimize performance.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 6,
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
]
|
||||
],
|
||||
],
|
||||
@@ -359,9 +395,18 @@ return [
|
||||
'variables' => [
|
||||
[
|
||||
'name' => '_APP_STORAGE_LIMIT',
|
||||
'description' => 'Maximun file size allowed for file upload. The default value is 10MB limitation. You should pass your size limit value in bytes.',
|
||||
'description' => 'Maximum file size allowed for file upload. The default value is 30MB. You should pass your size limit value in bytes.',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => '10000000',
|
||||
'default' => '30000000',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_PREVIEW_LIMIT',
|
||||
'description' => 'Maximum file size allowed for file image preview. The default value is 20MB. You should pass your size limit value in bytes.',
|
||||
'introduction' => '0.13.4',
|
||||
'default' => '20000000',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
@@ -393,12 +438,93 @@ return [
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_DEVICE',
|
||||
'description' => 'Select default storage device. The default value is \'Local\'. List of supported adapters are \'Local\', \'S3\' and \'DOSpaces\'.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'Local',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_S3_ACCESS_KEY',
|
||||
'description' => 'AWS S3 storage access key. Required when the storage adapter is set to S3. You can get your access key from your AWS console',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_S3_SECRET',
|
||||
'description' => 'AWS S3 storage secret key. Required when the storage adapter is set to S3. You can get your secret key from your AWS console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_S3_REGION',
|
||||
'description' => 'AWS S3 storage region. Required when storage adapter is set to S3. You can find your region info for your bucket from AWS console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'us-eas-1',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_S3_BUCKET',
|
||||
'description' => 'AWS S3 storage bucket. Required when storage adapter is set to S3. You can create buckets in your AWS console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_DO_SPACES_ACCESS_KEY',
|
||||
'description' => 'DigitalOcean spaces access key. Required when the storage adapter is set to DOSpaces. You can get your access key from your DigitalOcean console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_DO_SPACES_SECRET',
|
||||
'description' => 'DigitalOcean spaces secret key. Required when the storage adapter is set to DOSpaces. You can get your secret key from your DigitalOcean console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_DO_SPACES_REGION',
|
||||
'description' => 'DigitalOcean spaces region. Required when storage adapter is set to DOSpaces. You can find your region info for your space from DigitalOcean console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'us-eas-1',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
[
|
||||
'name' => '_APP_STORAGE_DO_SPACES_BUCKET',
|
||||
'description' => 'DigitalOcean spaces bucket. Required when storage adapter is set to DOSpaces. You can create spaces in your DigitalOcean console.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'category' => 'Functions',
|
||||
'description' => '',
|
||||
'variables' => [
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_SIZE_LIMIT',
|
||||
'description' => 'The maximum size deployment in bytes. The default value is 30MB.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '30000000',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_TIMEOUT',
|
||||
'description' => 'The maximum number of seconds allowed as a timeout value when creating a new function. The default value is 900 seconds.',
|
||||
@@ -408,6 +534,15 @@ return [
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_BUILD_TIMEOUT',
|
||||
'description' => 'The maximum number of seconds allowed as a timeout value when building a new function. The default value is 900 seconds.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '900',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_CONTAINERS',
|
||||
'description' => 'The maximum number of containers Appwrite is allowed to keep alive in the background for function environments. Running containers allow faster execution time as there is no need to recreate each container every time a function gets executed. The default value is 10.',
|
||||
@@ -421,7 +556,7 @@ return [
|
||||
'name' => '_APP_FUNCTIONS_CPUS',
|
||||
'description' => 'The maximum number of CPU core a single cloud function is allowed to use. Please note that setting a value higher than available cores will result in a function error, which might result in an error. The default value is empty. When it\'s empty, CPU limit will be disabled.',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => '',
|
||||
'default' => '0',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
@@ -430,7 +565,7 @@ return [
|
||||
'name' => '_APP_FUNCTIONS_MEMORY',
|
||||
'description' => 'The maximum amount of memory a single cloud function is allowed to use in megabytes. The default value is empty. When it\'s empty, memory limit will be disabled.',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => '256',
|
||||
'default' => '0',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
@@ -439,7 +574,7 @@ return [
|
||||
'name' => '_APP_FUNCTIONS_MEMORY_SWAP',
|
||||
'description' => 'The maximum amount of swap memory a single cloud function is allowed to use in megabytes. The default value is empty. When it\'s empty, swap memory limit will be disabled.',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => '256',
|
||||
'default' => '0',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
@@ -448,16 +583,43 @@ return [
|
||||
'name' => '_APP_FUNCTIONS_RUNTIMES',
|
||||
'description' => "This option allows you to limit the available environments for cloud functions. This option is very useful for low-cost servers to safe disk space.\n\nTo enable/activate this option, pass a list of allowed environments separated by a comma.\n\nCurrently, supported environments are: " . \implode(', ', \array_keys(Config::getParam('runtimes'))),
|
||||
'introduction' => '0.8.0',
|
||||
'default' => 'node-16.0,php-8.0,python-3.9,ruby-3.0,java-16.0',
|
||||
'default' => 'node-16.0,php-8.0,python-3.9,ruby-3.0',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_EXECUTOR_SECRET',
|
||||
'description' => 'The secret key used by Appwrite to communicate with the function executor. Make sure to change this!',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'your-secret-key',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_EXECUTOR_RUNTIME_NETWORK',
|
||||
'description' => 'The docker network used for communication between the executor and runtimes. Change this if you have altered the default network names.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'appwrite_runtimes',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_ENVS',
|
||||
'description' => 'Deprectated with 0.8.0, use \'_APP_FUNCTIONS_RUNTIMES\' instead!',
|
||||
'description' => 'Deprecated with 0.8.0, use \'_APP_FUNCTIONS_RUNTIMES\' instead!',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => 'node-16.0,php-7.4,python-3.9,ruby-3.0,java-16.0',
|
||||
'default' => 'node-16.0,php-7.4,python-3.9,ruby-3.0',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_INACTIVE_THRESHOLD',
|
||||
'description' => 'The minimum time a function can be inactive before it\'s container is shutdown and put to sleep. The default value is 60 seconds',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => '60',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
@@ -533,4 +695,4 @@ return [
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Exception;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\HexColor;
|
||||
@@ -25,15 +25,15 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
|
||||
$set = Config::getParam('avatar-' . $type, []);
|
||||
|
||||
if (empty($set)) {
|
||||
throw new Exception('Avatar set not found', 404);
|
||||
throw new Exception('Avatar set not found', 404, Exception::AVATAR_SET_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!\array_key_exists($code, $set)) {
|
||||
throw new Exception('Avatar not found', 404);
|
||||
throw new Exception('Avatar not found', 404, Exception::AVATAR_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!\extension_loaded('imagick')) {
|
||||
throw new Exception('Imagick extension is missing', 500);
|
||||
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$output = 'png';
|
||||
@@ -43,7 +43,7 @@ $avatarCallback = function ($type, $code, $width, $height, $quality, $response)
|
||||
$type = 'png';
|
||||
|
||||
if (!\is_readable($path)) {
|
||||
throw new Exception('File not readable in ' . $path, 500);
|
||||
throw new Exception('File not readable in ' . $path, 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$cache = new Cache(new Filesystem(APP_STORAGE_CACHE . '/app-0')); // Limit file number or size
|
||||
@@ -95,9 +95,7 @@ App::get('/v1/avatars/credit-cards/:code')
|
||||
->param('height', 100, new Range(0, 2000), 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('quality', 100, new Range(0, 100), 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
->inject('response')
|
||||
->action(function ($code, $width, $height, $quality, $response) use ($avatarCallback) {
|
||||
return $avatarCallback('credit-cards', $code, $width, $height, $quality, $response);
|
||||
});
|
||||
->action(fn($code, $width, $height, $quality, $response) => $avatarCallback('credit-cards', $code, $width, $height, $quality, $response));
|
||||
|
||||
App::get('/v1/avatars/browsers/:code')
|
||||
->desc('Get Browser Icon')
|
||||
@@ -115,9 +113,7 @@ App::get('/v1/avatars/browsers/:code')
|
||||
->param('height', 100, new Range(0, 2000), 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('quality', 100, new Range(0, 100), 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
->inject('response')
|
||||
->action(function ($code, $width, $height, $quality, $response) use ($avatarCallback) {
|
||||
return $avatarCallback('browsers', $code, $width, $height, $quality, $response);
|
||||
});
|
||||
->action(fn($code, $width, $height, $quality, $response) => $avatarCallback('browsers', $code, $width, $height, $quality, $response));
|
||||
|
||||
App::get('/v1/avatars/flags/:code')
|
||||
->desc('Get Country Flag')
|
||||
@@ -135,9 +131,7 @@ App::get('/v1/avatars/flags/:code')
|
||||
->param('height', 100, new Range(0, 2000), 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
|
||||
->param('quality', 100, new Range(0, 100), 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
|
||||
->inject('response')
|
||||
->action(function ($code, $width, $height, $quality, $response) use ($avatarCallback) {
|
||||
return $avatarCallback('flags', $code, $width, $height, $quality, $response);
|
||||
});
|
||||
->action(fn($code, $width, $height, $quality, $response) => $avatarCallback('flags', $code, $width, $height, $quality, $response));
|
||||
|
||||
App::get('/v1/avatars/image')
|
||||
->desc('Get Image from URL')
|
||||
@@ -150,7 +144,7 @@ App::get('/v1/avatars/image')
|
||||
->label('sdk.description', '/docs/references/avatars/get-image.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_IMAGE)
|
||||
->param('url', '', new URL(), 'Image URL which you want to crop.')
|
||||
->param('url', '', new URL(['http', 'https']), 'Image URL which you want to crop.')
|
||||
->param('width', 400, new Range(0, 2000), 'Resize preview image width, Pass an integer between 0 to 2000.', true)
|
||||
->param('height', 400, new Range(0, 2000), 'Resize preview image height, Pass an integer between 0 to 2000.', true)
|
||||
->inject('response')
|
||||
@@ -175,19 +169,19 @@ App::get('/v1/avatars/image')
|
||||
}
|
||||
|
||||
if (!\extension_loaded('imagick')) {
|
||||
throw new Exception('Imagick extension is missing', 500);
|
||||
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$fetch = @\file_get_contents($url, false);
|
||||
|
||||
if (!$fetch) {
|
||||
throw new Exception('Image not found', 404);
|
||||
throw new Exception('Image not found', 404, Exception::AVATAR_IMAGE_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$image = new Image($fetch);
|
||||
} catch (\Exception$exception) {
|
||||
throw new Exception('Unable to parse image', 500);
|
||||
throw new Exception('Unable to parse image', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$image->crop((int) $width, (int) $height);
|
||||
@@ -219,7 +213,7 @@ App::get('/v1/avatars/favicon')
|
||||
->label('sdk.description', '/docs/references/avatars/get-favicon.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_IMAGE)
|
||||
->param('url', '', new URL(), 'Website URL which you want to fetch the favicon from.')
|
||||
->param('url', '', new URL(['http', 'https']), 'Website URL which you want to fetch the favicon from.')
|
||||
->inject('response')
|
||||
->action(function ($url, $response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
@@ -244,7 +238,7 @@ App::get('/v1/avatars/favicon')
|
||||
}
|
||||
|
||||
if (!\extension_loaded('imagick')) {
|
||||
throw new Exception('Imagick extension is missing', 500);
|
||||
throw new Exception('Imagick extension is missing', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$curl = \curl_init();
|
||||
@@ -265,7 +259,7 @@ App::get('/v1/avatars/favicon')
|
||||
\curl_close($curl);
|
||||
|
||||
if (!$html) {
|
||||
throw new Exception('Failed to fetch remote URL', 404);
|
||||
throw new Exception('Failed to fetch remote URL', 404, Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
@@ -323,7 +317,7 @@ App::get('/v1/avatars/favicon')
|
||||
$data = @\file_get_contents($outputHref, false);
|
||||
|
||||
if (empty($data) || (\mb_substr($data, 0, 5) === '<html') || \mb_substr($data, 0, 5) === '<!doc') {
|
||||
throw new Exception('Favicon not found', 404);
|
||||
throw new Exception('Favicon not found', 404, Exception::AVATAR_ICON_NOT_FOUND);
|
||||
}
|
||||
|
||||
$cache->save($key, $data);
|
||||
@@ -339,7 +333,7 @@ App::get('/v1/avatars/favicon')
|
||||
$fetch = @\file_get_contents($outputHref, false);
|
||||
|
||||
if (!$fetch) {
|
||||
throw new Exception('Icon not found', 404);
|
||||
throw new Exception('Icon not found', 404, Exception::AVATAR_ICON_NOT_FOUND);
|
||||
}
|
||||
|
||||
$image = new Image($fetch);
|
||||
@@ -424,7 +418,7 @@ App::get('/v1/avatars/initials')
|
||||
->inject('user')
|
||||
->action(function ($name, $width, $height, $color, $background, $response, $user) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
||||
$themes = [
|
||||
['color' => '#27005e', 'background' => '#e1d2f6'], // VIOLET
|
||||
@@ -443,6 +437,9 @@ App::get('/v1/avatars/initials')
|
||||
|
||||
$name = (!empty($name)) ? $name : $user->getAttribute('name', $user->getAttribute('email', ''));
|
||||
$words = \explode(' ', \strtoupper($name));
|
||||
// if there is no space, try to split by `_` underscore
|
||||
$words = (count($words) == 1 ) ? \explode('_', \strtoupper($name)) : $words;
|
||||
|
||||
$initials = null;
|
||||
$code = 0;
|
||||
|
||||
@@ -455,7 +452,6 @@ App::get('/v1/avatars/initials')
|
||||
}
|
||||
}
|
||||
|
||||
$length = \count($words);
|
||||
$rand = \substr($code, -1);
|
||||
$background = (!empty($background)) ? '#' . $background : $themes[$rand]['background'];
|
||||
$color = (!empty($color)) ? '#' . $color : $themes[$rand]['color'];
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Appwrite\ClamAV\Network;
|
||||
use Appwrite\Event\Event;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
App::get('/v1/health')
|
||||
->desc('Get HTTP')
|
||||
@@ -15,22 +17,33 @@ App::get('/v1/health')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'get')
|
||||
->label('sdk.description', '/docs/references/health/get.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_STATUS)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
$output = [
|
||||
'status' => 'pass',
|
||||
'ping' => 0
|
||||
];
|
||||
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/version')
|
||||
->desc('Get Version')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_VERSION)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['version' => APP_VERSION_STABLE]);
|
||||
$response->dynamic(new Document([ 'version' => APP_VERSION_STABLE ]), Response::MODEL_HEALTH_VERSION);
|
||||
});
|
||||
|
||||
App::get('/v1/health/db')
|
||||
@@ -41,14 +54,36 @@ App::get('/v1/health/db')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getDB')
|
||||
->label('sdk.description', '/docs/references/health/get-db.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_STATUS)
|
||||
->inject('response')
|
||||
->inject('utopia')
|
||||
->action(function ($response, $utopia) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\App $utopia */
|
||||
$utopia->getResource('db');
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
$checkStart = \microtime(true);
|
||||
|
||||
try {
|
||||
$db = $utopia->getResource('db'); /* @var $db PDO */
|
||||
|
||||
// Run a small test to check the connection
|
||||
$statement = $db->prepare("SELECT 1;");
|
||||
|
||||
$statement->closeCursor();
|
||||
|
||||
$statement->execute();
|
||||
} catch (Exception $_e) {
|
||||
throw new Exception('Database is not available', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$output = [
|
||||
'status' => 'pass',
|
||||
'ping' => \round((\microtime(true) - $checkStart) / 1000)
|
||||
];
|
||||
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/cache')
|
||||
@@ -59,14 +94,30 @@ App::get('/v1/health/cache')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getCache')
|
||||
->label('sdk.description', '/docs/references/health/get-cache.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_STATUS)
|
||||
->inject('response')
|
||||
->inject('utopia')
|
||||
->action(function ($response, $utopia) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\App $utopia */
|
||||
$utopia->getResource('cache');
|
||||
/** @var Redis */
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
$checkStart = \microtime(true);
|
||||
|
||||
$redis = $utopia->getResource('cache');
|
||||
|
||||
if (!$redis->ping(true)) {
|
||||
throw new Exception('Cache is not available', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$output = [
|
||||
'status' => 'pass',
|
||||
'ping' => \round((\microtime(true) - $checkStart) / 1000)
|
||||
];
|
||||
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/time')
|
||||
@@ -77,6 +128,9 @@ App::get('/v1/health/time')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getTime')
|
||||
->label('sdk.description', '/docs/references/health/get-time.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_TIME)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
@@ -112,10 +166,16 @@ App::get('/v1/health/time')
|
||||
$diff = ($timestamp - \time());
|
||||
|
||||
if ($diff > $gap || $diff < ($gap * -1)) {
|
||||
throw new Exception('Server time gaps detected');
|
||||
throw new Exception('Server time gaps detected', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$response->json(['remote' => $timestamp, 'local' => \time(), 'diff' => $diff]);
|
||||
$output = [
|
||||
'remoteTime' => $timestamp,
|
||||
'localTime' => \time(),
|
||||
'diff' => $diff
|
||||
];
|
||||
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_TIME);
|
||||
});
|
||||
|
||||
App::get('/v1/health/queue/webhooks')
|
||||
@@ -126,26 +186,14 @@ App::get('/v1/health/queue/webhooks')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueWebhooks')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-webhooks.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['size' => Resque::size(Event::WEBHOOK_QUEUE_NAME)]);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/tasks')
|
||||
->desc('Get Tasks Queue')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueTasks')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-tasks.md')
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['size' => Resque::size(Event::TASK_QUEUE_NAME)]);
|
||||
$response->dynamic(new Document([ 'size' => Resque::size(Event::WEBHOOK_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/logs')
|
||||
@@ -156,11 +204,14 @@ App::get('/v1/health/queue/logs')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueLogs')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-logs.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['size' => Resque::size(Event::AUDITS_QUEUE_NAME)]);
|
||||
$response->dynamic(new Document([ 'size' => Resque::size(Event::AUDITS_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/usage')
|
||||
@@ -171,11 +222,14 @@ App::get('/v1/health/queue/usage')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueUsage')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-usage.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['size' => Resque::size(Event::USAGE_QUEUE_NAME)]);
|
||||
$response->dynamic(new Document([ 'size' => Resque::size(Event::USAGE_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/certificates')
|
||||
@@ -186,11 +240,14 @@ App::get('/v1/health/queue/certificates')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueCertificates')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-certificates.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['size' => Resque::size(Event::CERTIFICATES_QUEUE_NAME)]);
|
||||
$response->dynamic(new Document([ 'size' => Resque::size(Event::CERTIFICATES_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/functions')
|
||||
@@ -201,11 +258,14 @@ App::get('/v1/health/queue/functions')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueFunctions')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-functions.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->json(['size' => Resque::size(Event::FUNCTIONS_QUEUE_NAME)]);
|
||||
$response->dynamic(new Document([ 'size' => Resque::size(Event::FUNCTIONS_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/storage/local')
|
||||
@@ -216,10 +276,15 @@ App::get('/v1/health/storage/local')
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getStorageLocal')
|
||||
->label('sdk.description', '/docs/references/health/get-storage-local.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_STATUS)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$checkStart = \microtime(true);
|
||||
|
||||
foreach ([
|
||||
'Uploads' => APP_STORAGE_UPLOADS,
|
||||
'Cache' => APP_STORAGE_CACHE,
|
||||
@@ -229,49 +294,58 @@ App::get('/v1/health/storage/local')
|
||||
$device = new Local($volume);
|
||||
|
||||
if (!\is_readable($device->getRoot())) {
|
||||
throw new Exception('Device '.$key.' dir is not readable');
|
||||
throw new Exception('Device '.$key.' dir is not readable', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
if (!\is_writable($device->getRoot())) {
|
||||
throw new Exception('Device '.$key.' dir is not writable');
|
||||
throw new Exception('Device '.$key.' dir is not writable', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
$response->json(['status' => 'OK']);
|
||||
$output = [
|
||||
'status' => 'pass',
|
||||
'ping' => \round((\microtime(true) - $checkStart) / 1000)
|
||||
];
|
||||
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/anti-virus')
|
||||
->desc('Get Anti virus')
|
||||
->desc('Get Antivirus')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getAntiVirus')
|
||||
->label('sdk.method', 'getAntivirus')
|
||||
->label('sdk.description', '/docs/references/health/get-storage-anti-virus.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_ANTIVIRUS)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$output = [
|
||||
'status' => '',
|
||||
'version' => ''
|
||||
];
|
||||
|
||||
if (App::getEnv('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled
|
||||
return $response->json([
|
||||
'status' => 'disabled',
|
||||
'version' => '',
|
||||
]);
|
||||
$output['status'] = 'disabled';
|
||||
$output['version'] = '';
|
||||
} else {
|
||||
$antivirus = new Network(App::getEnv('_APP_STORAGE_ANTIVIRUS_HOST', 'clamav'),
|
||||
(int) App::getEnv('_APP_STORAGE_ANTIVIRUS_PORT', 3310));
|
||||
|
||||
try {
|
||||
$output['version'] = @$antivirus->version();
|
||||
$output['status'] = (@$antivirus->ping()) ? 'pass' : 'fail';
|
||||
} catch( \Exception $e) {
|
||||
throw new Exception('Antivirus is not available', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
$antiVirus = new Network(App::getEnv('_APP_STORAGE_ANTIVIRUS_HOST', 'clamav'),
|
||||
(int) App::getEnv('_APP_STORAGE_ANTIVIRUS_PORT', 3310));
|
||||
try {
|
||||
$response->json([
|
||||
'status' => (@$antiVirus->ping()) ? 'online' : 'offline',
|
||||
'version' => @$antiVirus->version(),
|
||||
]);
|
||||
} catch( \Exception $e) {
|
||||
$response->json([
|
||||
'status' => 'offline',
|
||||
'version' => '',
|
||||
]);
|
||||
}
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_ANTIVIRUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/stats') // Currently only used internally
|
||||
@@ -284,11 +358,12 @@ App::get('/v1/health/stats') // Currently only used internally
|
||||
->label('docs', false)
|
||||
->inject('response')
|
||||
->inject('register')
|
||||
->action(function ($response, $register) {
|
||||
->inject('deviceFiles')
|
||||
->action(function ($response, $register, $deviceFiles) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
/** @var Utopia\Storage\Device $deviceFiles */
|
||||
|
||||
$device = Storage::getDevice('files');
|
||||
$cache = $register->get('cache');
|
||||
|
||||
$cacheStats = $cache->info();
|
||||
@@ -296,9 +371,9 @@ App::get('/v1/health/stats') // Currently only used internally
|
||||
$response
|
||||
->json([
|
||||
'storage' => [
|
||||
'used' => Storage::human($device->getDirectorySize($device->getRoot().'/')),
|
||||
'partitionTotal' => Storage::human($device->getPartitionTotalSpace()),
|
||||
'partitionFree' => Storage::human($device->getPartitionFreeSpace()),
|
||||
'used' => Storage::human($deviceFiles->getDirectorySize($deviceFiles->getRoot().'/')),
|
||||
'partitionTotal' => Storage::human($deviceFiles->getPartitionTotalSpace()),
|
||||
'partitionFree' => Storage::human($deviceFiles->getPartitionFreeSpace()),
|
||||
],
|
||||
'cache' => [
|
||||
'uptime' => $cacheStats['uptime_in_seconds'] ?? 0,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Utopia\Database\Document;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Config\Config;
|
||||
@@ -21,7 +21,7 @@ App::get('/v1/locale')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function ($request, $response, $locale, $geodb) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
@@ -100,7 +100,7 @@ App::get('/v1/locale/countries')
|
||||
return strcmp($a->getAttribute('name'), $b->getAttribute('name'));
|
||||
});
|
||||
|
||||
$response->dynamic(new Document(['countries' => $output, 'sum' => \count($output)]), Response::MODEL_COUNTRY_LIST);
|
||||
$response->dynamic(new Document(['countries' => $output, 'total' => \count($output)]), Response::MODEL_COUNTRY_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/locale/countries/eu')
|
||||
@@ -136,7 +136,7 @@ App::get('/v1/locale/countries/eu')
|
||||
return strcmp($a->getAttribute('name'), $b->getAttribute('name'));
|
||||
});
|
||||
|
||||
$response->dynamic(new Document(['countries' => $output, 'sum' => \count($output)]), Response::MODEL_COUNTRY_LIST);
|
||||
$response->dynamic(new Document(['countries' => $output, 'total' => \count($output)]), Response::MODEL_COUNTRY_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/locale/countries/phones')
|
||||
@@ -171,7 +171,7 @@ App::get('/v1/locale/countries/phones')
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document(['phones' => $output, 'sum' => \count($output)]), Response::MODEL_PHONE_LIST);
|
||||
$response->dynamic(new Document(['phones' => $output, 'total' => \count($output)]), Response::MODEL_PHONE_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/locale/continents')
|
||||
@@ -204,7 +204,7 @@ App::get('/v1/locale/continents')
|
||||
return strcmp($a->getAttribute('name'), $b->getAttribute('name'));
|
||||
});
|
||||
|
||||
$response->dynamic(new Document(['continents' => $output, 'sum' => \count($output)]), Response::MODEL_CONTINENT_LIST);
|
||||
$response->dynamic(new Document(['continents' => $output, 'total' => \count($output)]), Response::MODEL_CONTINENT_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/locale/currencies')
|
||||
@@ -224,11 +224,9 @@ App::get('/v1/locale/currencies')
|
||||
|
||||
$list = Config::getParam('locale-currencies');
|
||||
|
||||
$list = array_map(function($node) {
|
||||
return new Document($node);
|
||||
}, $list);
|
||||
$list = array_map(fn($node) => new Document($node), $list);
|
||||
|
||||
$response->dynamic(new Document(['currencies' => $list, 'sum' => \count($list)]), Response::MODEL_CURRENCY_LIST);
|
||||
$response->dynamic(new Document(['currencies' => $list, 'total' => \count($list)]), Response::MODEL_CURRENCY_LIST);
|
||||
});
|
||||
|
||||
|
||||
@@ -249,9 +247,7 @@ App::get('/v1/locale/languages')
|
||||
|
||||
$list = Config::getParam('locale-languages');
|
||||
|
||||
$list = array_map(function($node) {
|
||||
return new Document($node);
|
||||
}, $list);
|
||||
$list = array_map(fn ($node) => new Document($node), $list);
|
||||
|
||||
$response->dynamic(new Document(['languages' => $list, 'sum' => \count($list)]), Response::MODEL_LANGUAGE_LIST);
|
||||
$response->dynamic(new Document(['languages' => $list, 'total' => \count($list)]), Response::MODEL_LANGUAGE_LIST);
|
||||
});
|
||||
@@ -3,37 +3,63 @@
|
||||
require_once __DIR__.'/../init.php';
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\Swoole\Request;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Log\User;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\View;
|
||||
use Utopia\Exception;
|
||||
use Appwrite\Utopia\View;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Domains\Domain;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Response\Filters\V06;
|
||||
use Appwrite\Utopia\Response\Filters\V07;
|
||||
use Appwrite\Utopia\Response\Filters\V08;
|
||||
use Appwrite\Utopia\Response\Filters\V11 as ResponseV11;
|
||||
use Appwrite\Utopia\Response\Filters\V12 as ResponseV12;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Appwrite\Utopia\Request\Filters\V12 as RequestV12;
|
||||
use Appwrite\Utopia\Request\Filters\V13 as RequestV13;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
Config::setParam('domainVerification', false);
|
||||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $consoleDB, $user, $locale, $clients) {
|
||||
App::init(function ($utopia, $request, $response, $console, $project, $dbForConsole, $user, $locale, $clients) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $console */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $consoleDB */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Database\Document $console */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForConsole */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var array $clients */
|
||||
|
||||
/*
|
||||
* Request format
|
||||
*/
|
||||
$route = $utopia->match($request);
|
||||
Request::setRoute($route);
|
||||
|
||||
$requestFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
|
||||
if ($requestFormat) {
|
||||
switch($requestFormat) {
|
||||
case version_compare ($requestFormat , '0.12.0', '<') :
|
||||
Request::setFilter(new RequestV12());
|
||||
break;
|
||||
case version_compare ($requestFormat , '0.13.0', '<') :
|
||||
Request::setFilter(new RequestV13());
|
||||
break;
|
||||
default:
|
||||
Request::setFilter(null);
|
||||
}
|
||||
} else {
|
||||
Request::setFilter(null);
|
||||
}
|
||||
|
||||
$domain = $request->getHostname();
|
||||
$domains = Config::getParam('domains', []);
|
||||
if (!array_key_exists($domain, $domains)) {
|
||||
@@ -46,54 +72,50 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
Console::warning('Skipping SSL certificates generation on ACME challenge.');
|
||||
} else {
|
||||
Authorization::disable();
|
||||
$dbDomain = $consoleDB->getCollectionFirst([
|
||||
'limit' => 1,
|
||||
'offset' => 0,
|
||||
'filters' => [
|
||||
'$collection=' . Database::SYSTEM_COLLECTION_CERTIFICATES,
|
||||
'domain=' . $domain->get(),
|
||||
],
|
||||
|
||||
$domainDocument = $dbForConsole->findOne('domains', [
|
||||
new Query('domain', QUERY::TYPE_EQUAL, [$domain->get()])
|
||||
]);
|
||||
|
||||
if (empty($dbDomain)) {
|
||||
$dbDomain = [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_CERTIFICATES,
|
||||
'$permissions' => [
|
||||
'read' => [],
|
||||
'write' => [],
|
||||
],
|
||||
if (!$domainDocument) {
|
||||
$domainDocument = new Document([
|
||||
'domain' => $domain->get(),
|
||||
];
|
||||
$dbDomain = $consoleDB->createDocument($dbDomain);
|
||||
Authorization::enable();
|
||||
'tld' => $domain->getSuffix(),
|
||||
'registerable' => $domain->getRegisterable(),
|
||||
'verification' => false,
|
||||
'certificateId' => null,
|
||||
]);
|
||||
|
||||
Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...'); // TODO move this to installation script
|
||||
$domainDocument = $dbForConsole->createDocument('domains', $domainDocument);
|
||||
|
||||
Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...');
|
||||
|
||||
Resque::enqueue('v1-certificates', 'CertificatesV1', [
|
||||
'document' => $dbDomain,
|
||||
'document' => $domainDocument,
|
||||
'domain' => $domain->get(),
|
||||
'validateTarget' => false,
|
||||
'validateCNAME' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
$domains[$domain->get()] = true;
|
||||
|
||||
Authorization::reset(); // ensure authorization is re-enabled
|
||||
}
|
||||
Config::setParam('domains', $domains);
|
||||
}
|
||||
|
||||
|
||||
$localeParam = (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', ''));
|
||||
|
||||
$localeParam = (string) $request->getParam('locale', $request->getHeader('x-appwrite-locale', ''));
|
||||
if (\in_array($localeParam, Config::getParam('locale-codes'))) {
|
||||
$locale->setDefault($localeParam);
|
||||
};
|
||||
}
|
||||
|
||||
$route = $utopia->match($request);
|
||||
if ($project->isEmpty()) {
|
||||
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
var_dump("*********** In general.php init with route {$route->getPath()} *************");
|
||||
|
||||
if (!empty($route->getLabel('sdk.auth', [])) && empty($project->getId()) && ($route->getLabel('scope', '') !== 'public')) {
|
||||
throw new Exception('Missing or unknown project ID', 400);
|
||||
if (!empty($route->getLabel('sdk.auth', [])) && $project->isEmpty() && ($route->getLabel('scope', '') !== 'public')) {
|
||||
throw new Exception('Missing or unknown project ID', 400, Exception::PROJECT_UNKNOWN);
|
||||
}
|
||||
|
||||
$referrer = $request->getReferer();
|
||||
@@ -111,16 +133,6 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
$selfDomain = new Domain($request->getHostname());
|
||||
$endDomain = new Domain((string)$origin);
|
||||
|
||||
// var_dump('referer', $referrer);
|
||||
// var_dump('origin', $origin);
|
||||
// var_dump('port', $request->getPort());
|
||||
// var_dump('hostname', $request->getHostname());
|
||||
// var_dump('protocol', $request->getProtocol());
|
||||
// var_dump('method', $request->getMethod());
|
||||
// var_dump('ip', $request->getIP());
|
||||
// var_dump('-----------------');
|
||||
// var_dump($request->debug());
|
||||
|
||||
Config::setParam('domainVerification',
|
||||
($selfDomain->getRegisterable() === $endDomain->getRegisterable()) &&
|
||||
$endDomain->getRegisterable() !== '');
|
||||
@@ -135,19 +147,16 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
);
|
||||
|
||||
/*
|
||||
* Response format
|
||||
*/
|
||||
* Response format
|
||||
*/
|
||||
$responseFormat = $request->getHeader('x-appwrite-response-format', App::getEnv('_APP_SYSTEM_RESPONSE_FORMAT', ''));
|
||||
if ($responseFormat) {
|
||||
switch($responseFormat) {
|
||||
case version_compare ($responseFormat , '0.6.2', '<=') :
|
||||
Response::setFilter(new V06());
|
||||
case version_compare ($responseFormat , '0.11.2', '<=') :
|
||||
Response::setFilter(new ResponseV11());
|
||||
break;
|
||||
case version_compare ($responseFormat , '0.7.2', '<=') :
|
||||
Response::setFilter(new V07());
|
||||
break;
|
||||
case version_compare ($responseFormat , '0.8.0', '<=') :
|
||||
Response::setFilter(new V08());
|
||||
case version_compare ($responseFormat , '0.12.4', '<='):
|
||||
Response::setFilter(new ResponseV12());
|
||||
break;
|
||||
default:
|
||||
Response::setFilter(null);
|
||||
@@ -174,7 +183,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
->addHeader('Server', 'Appwrite')
|
||||
->addHeader('X-Content-Type-Options', 'nosniff')
|
||||
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, Cache-Control, Expires, Pragma')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, X-Appwrite-ID, Content-Range, Range, Cache-Control, Expires, Pragma')
|
||||
->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Origin', $refDomain)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true')
|
||||
@@ -192,7 +201,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
&& \in_array($request->getMethod(), [Request::METHOD_POST, Request::METHOD_PUT, Request::METHOD_PATCH, Request::METHOD_DELETE])
|
||||
&& $route->getLabel('origin', false) !== '*'
|
||||
&& empty($request->getHeader('x-appwrite-key', ''))) {
|
||||
throw new Exception($originValidator->getDescription(), 403);
|
||||
throw new Exception($originValidator->getDescription(), 403, Exception::GENERAL_UNKNOWN_ORIGIN);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -201,10 +210,10 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
$role = ($user->isEmpty()) ? Auth::USER_ROLE_GUEST : Auth::USER_ROLE_MEMBER;
|
||||
|
||||
// Add user roles
|
||||
$membership = $user->search('teamId', $project->getAttribute('teamId', null), $user->getAttribute('memberships', []));
|
||||
$memberships = $user->find('teamId', $project->getAttribute('teamId', null), 'memberships');
|
||||
|
||||
if ($membership) {
|
||||
foreach ($membership->getAttribute('roles', []) as $memberRole) {
|
||||
if ($memberships) {
|
||||
foreach ($memberships->getAttribute('roles', []) as $memberRole) {
|
||||
switch ($memberRole) {
|
||||
case 'owner':
|
||||
$role = Auth::USER_ROLE_OWNER;
|
||||
@@ -227,7 +236,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
|
||||
if (!empty($authKey)) { // API Key authentication
|
||||
// Check if given key match project API keys
|
||||
$key = $project->search('secret', $authKey, $project->getAttribute('keys', []));
|
||||
$key = $project->find('secret', $authKey, 'keys');
|
||||
|
||||
/*
|
||||
* Try app auth when we have project key and no user
|
||||
@@ -236,7 +245,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
if ($key && $user->isEmpty()) {
|
||||
$user = new Document([
|
||||
'$id' => '',
|
||||
'status' => Auth::USER_STATUS_ACTIVATED,
|
||||
'status' => true,
|
||||
'email' => 'app.'.$project->getId().'@service.'.$request->getHostname(),
|
||||
'password' => '',
|
||||
'name' => $project->getAttribute('name', 'Untitled'),
|
||||
@@ -256,28 +265,35 @@ App::init(function ($utopia, $request, $response, $console, $project, $consoleDB
|
||||
Authorization::setRole($authRole);
|
||||
}
|
||||
|
||||
// TDOO Check if user is root
|
||||
|
||||
if (!\in_array($scope, $scopes)) {
|
||||
if (empty($project->getId()) || Database::SYSTEM_COLLECTION_PROJECTS !== $project->getCollection()) { // Check if permission is denied because project is missing
|
||||
throw new Exception('Project not found', 404);
|
||||
$service = $route->getLabel('sdk.namespace','');
|
||||
if(!empty($service)) {
|
||||
if(array_key_exists($service, $project->getAttribute('services',[]))
|
||||
&& !$project->getAttribute('services',[])[$service]
|
||||
&& !Auth::isPrivilegedUser(Authorization::getRoles())) {
|
||||
throw new Exception('Service is disabled', 503, Exception::GENERAL_SERVICE_DISABLED);
|
||||
}
|
||||
|
||||
throw new Exception($user->getAttribute('email', 'User').' (role: '.\strtolower($roles[$role]['label']).') missing scope ('.$scope.')', 401);
|
||||
}
|
||||
|
||||
if (Auth::USER_STATUS_BLOCKED == $user->getAttribute('status')) { // Account has not been activated
|
||||
throw new Exception('Invalid credentials. User is blocked', 401); // User is in status blocked
|
||||
if (!\in_array($scope, $scopes)) {
|
||||
if ($project->isEmpty()) { // Check if permission is denied because project is missing
|
||||
throw new Exception('Project not found', 404, Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
throw new Exception($user->getAttribute('email', 'User').' (role: '.\strtolower($roles[$role]['label']).') missing scope ('.$scope.')', 401, Exception::GENERAL_UNAUTHORIZED_SCOPE);
|
||||
}
|
||||
|
||||
if (false === $user->getAttribute('status')) { // Account is blocked
|
||||
throw new Exception('Invalid credentials. User is blocked', 401, Exception::USER_BLOCKED);
|
||||
}
|
||||
|
||||
if ($user->getAttribute('reset')) {
|
||||
throw new Exception('Password reset is required', 412);
|
||||
throw new Exception('Password reset is required', 412, Exception::USER_PASSWORD_RESET_REQUIRED);
|
||||
}
|
||||
|
||||
}, ['utopia', 'request', 'response', 'console', 'project', 'consoleDB', 'user', 'locale', 'clients']);
|
||||
}, ['utopia', 'request', 'response', 'console', 'project', 'dbForConsole', 'user', 'locale', 'clients']);
|
||||
|
||||
App::options(function ($request, $response) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$origin = $request->getOrigin();
|
||||
@@ -285,27 +301,86 @@ App::options(function ($request, $response) {
|
||||
$response
|
||||
->addHeader('Server', 'Appwrite')
|
||||
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, Cache-Control, Expires, Pragma, X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-SDK-Version, X-Appwrite-ID, Content-Range, Range, Cache-Control, Expires, Pragma, X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Expose-Headers', 'X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Origin', $origin)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true')
|
||||
->noContent();
|
||||
}, ['request', 'response']);
|
||||
|
||||
App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
App::error(function ($error, $utopia, $request, $response, $layout, $project, $logger, $loggerBreadcrumbs) {
|
||||
/** @var Exception $error */
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\View $layout */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Utopia\View $layout */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Logger\Logger $logger */
|
||||
/** @var Utopia\Logger\Log\Breadcrumb[] $loggerBreadcrumbs */
|
||||
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
$route = $utopia->match($request);
|
||||
|
||||
/** Delegate PDO exceptions to the global handler so the database connection can be returned to the pool */
|
||||
if ($error instanceof PDOException) {
|
||||
throw $error;
|
||||
}
|
||||
|
||||
$route = $utopia->match($request);
|
||||
$template = ($route) ? $route->getLabel('error', null) : null;
|
||||
if($logger) {
|
||||
if($error->getCode() >= 500 || $error->getCode() === 0) {
|
||||
try {
|
||||
/** @var Utopia\Database\Document $user */
|
||||
$user = $utopia->getResource('user');
|
||||
} catch(\Throwable $th) {
|
||||
// All good, user is optional information for logger
|
||||
}
|
||||
|
||||
$log = new Utopia\Logger\Log();
|
||||
|
||||
if(isset($user) && !$user->isEmpty()) {
|
||||
$log->setUser(new User($user->getId()));
|
||||
}
|
||||
|
||||
$log->setNamespace("http");
|
||||
$log->setServer(\gethostname());
|
||||
$log->setVersion($version);
|
||||
$log->setType(Log::TYPE_ERROR);
|
||||
$log->setMessage($error->getMessage());
|
||||
|
||||
$log->addTag('method', $route->getMethod());
|
||||
$log->addTag('url', $route->getPath());
|
||||
$log->addTag('verboseType', get_class($error));
|
||||
$log->addTag('code', $error->getCode());
|
||||
$log->addTag('projectId', $project->getId());
|
||||
$log->addTag('hostname', $request->getHostname());
|
||||
$log->addTag('locale', (string)$request->getParam('locale', $request->getHeader('x-appwrite-locale', '')));
|
||||
|
||||
$log->addExtra('file', $error->getFile());
|
||||
$log->addExtra('line', $error->getLine());
|
||||
$log->addExtra('trace', $error->getTraceAsString());
|
||||
$log->addExtra('detailedTrace', $error->getTrace());
|
||||
$log->addExtra('roles', Authorization::$roles);
|
||||
|
||||
$action = $route->getLabel("sdk.namespace", "UNKNOWN_NAMESPACE") . '.' . $route->getLabel("sdk.method", "UNKNOWN_METHOD");
|
||||
$log->setAction($action);
|
||||
|
||||
$isProduction = App::getEnv('_APP_ENV', 'development') === 'production';
|
||||
$log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING);
|
||||
|
||||
foreach($loggerBreadcrumbs as $loggerBreadcrumb) {
|
||||
$log->addBreadcrumb($loggerBreadcrumb);
|
||||
}
|
||||
|
||||
$responseCode = $logger->addLog($log);
|
||||
Console::info('Log pushed with status code: '.$responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
$code = $error->getCode();
|
||||
$message = $error->getMessage();
|
||||
$file = $error->getFile();
|
||||
$line = $error->getLine();
|
||||
$trace = $error->getTrace();
|
||||
|
||||
if (php_sapi_name() === 'cli') {
|
||||
Console::error('[Error] Timestamp: '.date('c', time()));
|
||||
@@ -316,14 +391,30 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
}
|
||||
|
||||
Console::error('[Error] Type: '.get_class($error));
|
||||
Console::error('[Error] Message: '.$error->getMessage());
|
||||
Console::error('[Error] File: '.$error->getFile());
|
||||
Console::error('[Error] Line: '.$error->getLine());
|
||||
Console::error('[Error] Message: '.$message);
|
||||
Console::error('[Error] File: '.$file);
|
||||
Console::error('[Error] Line: '.$line);
|
||||
}
|
||||
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
/** Handle Utopia Errors */
|
||||
if ($error instanceof Utopia\Exception) {
|
||||
$error = new Exception($message, $code, Exception::GENERAL_UNKNOWN, $error);
|
||||
switch($code) {
|
||||
case 400:
|
||||
$error->setType(Exception::GENERAL_ARGUMENT_INVALID);
|
||||
break;
|
||||
case 404:
|
||||
$error->setType(Exception::GENERAL_ROUTE_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($error->getCode()) { // Don't show 500 errors!
|
||||
/** Wrap all exceptions inside Appwrite\Extend\Exception */
|
||||
if (!($error instanceof Exception)) {
|
||||
$error = new Exception($message, $code, Exception::GENERAL_UNKNOWN, $error);
|
||||
}
|
||||
|
||||
switch ($code) { // Don't show 500 errors!
|
||||
case 400: // Error allowed publicly
|
||||
case 401: // Error allowed publicly
|
||||
case 402: // Error allowed publicly
|
||||
@@ -331,11 +422,10 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
case 404: // Error allowed publicly
|
||||
case 409: // Error allowed publicly
|
||||
case 412: // Error allowed publicly
|
||||
case 416: // Error allowed publicly
|
||||
case 429: // Error allowed publicly
|
||||
case 501: // Error allowed publicly
|
||||
case 503: // Error allowed publicly
|
||||
$code = $error->getCode();
|
||||
$message = $error->getMessage();
|
||||
break;
|
||||
default:
|
||||
$code = 500; // All other errors get the generic 500 server error status code
|
||||
@@ -344,19 +434,21 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
|
||||
//$_SERVER = []; // Reset before reporting to error log to avoid keys being compromised
|
||||
|
||||
var_dump("*********** In general.php::error error->getCode() {$error->getCode()} *************");
|
||||
$type = $error->getType();
|
||||
|
||||
$output = ((App::isDevelopment())) ? [
|
||||
'message' => $error->getMessage(),
|
||||
'code' => $error->getCode(),
|
||||
'file' => $error->getFile(),
|
||||
'line' => $error->getLine(),
|
||||
'trace' => $error->getTrace(),
|
||||
'message' => $message,
|
||||
'code' => $code,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
'trace' => $trace,
|
||||
'version' => $version,
|
||||
'type' => $type,
|
||||
] : [
|
||||
'message' => $message,
|
||||
'code' => $code,
|
||||
'version' => $version,
|
||||
'type' => $type,
|
||||
];
|
||||
|
||||
$response
|
||||
@@ -366,14 +458,18 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
->setStatusCode($code)
|
||||
;
|
||||
|
||||
$template = ($route) ? $route->getLabel('error', null) : null;
|
||||
|
||||
if ($template) {
|
||||
$comp = new View($template);
|
||||
|
||||
$comp
|
||||
->setParam('development', App::isDevelopment())
|
||||
->setParam('projectName', $project->getAttribute('name'))
|
||||
->setParam('projectURL', $project->getAttribute('url'))
|
||||
->setParam('message', $error->getMessage())
|
||||
->setParam('code', $code)
|
||||
->setParam('trace', $trace)
|
||||
;
|
||||
|
||||
$layout
|
||||
@@ -389,7 +485,7 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) {
|
||||
|
||||
$response->dynamic(new Document($output),
|
||||
$utopia->isDevelopment() ? Response::MODEL_ERROR_DEV : Response::MODEL_ERROR);
|
||||
}, ['error', 'utopia', 'request', 'response', 'layout', 'project']);
|
||||
}, ['error', 'utopia', 'request', 'response', 'layout', 'project', 'logger', 'loggerBreadcrumbs']);
|
||||
|
||||
App::get('/manifest.json')
|
||||
->desc('Progressive app manifest file')
|
||||
@@ -445,12 +541,26 @@ App::get('/.well-known/acme-challenge')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->action(function ($request, $response) {
|
||||
$uriChunks = \explode('/', $request->getURI());
|
||||
$token = $uriChunks[\count($uriChunks) - 1];
|
||||
|
||||
$validator = new Text(100, [
|
||||
...Text::NUMBERS,
|
||||
...Text::ALPHABET_LOWER,
|
||||
...Text::ALPHABET_UPPER,
|
||||
'-',
|
||||
'_'
|
||||
]);
|
||||
|
||||
if (!$validator->isValid($token) || \count($uriChunks) !== 4) {
|
||||
throw new Exception('Invalid challenge token.', 400);
|
||||
}
|
||||
|
||||
$base = \realpath(APP_STORAGE_CERTIFICATES);
|
||||
$path = \str_replace('/.well-known/acme-challenge/', '', $request->getURI());
|
||||
$absolute = \realpath($base.'/.well-known/acme-challenge/'.$path);
|
||||
$absolute = \realpath($base.'/.well-known/acme-challenge/'.$token);
|
||||
|
||||
if (!$base) {
|
||||
throw new Exception('Storage error', 500);
|
||||
throw new Exception('Storage error', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
if (!$absolute) {
|
||||
@@ -468,7 +578,7 @@ App::get('/.well-known/acme-challenge')
|
||||
$content = @\file_get_contents($absolute);
|
||||
|
||||
if (!$content) {
|
||||
throw new Exception('Failed to get contents', 500);
|
||||
throw new Exception('Failed to get contents', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$response->text($content);
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
global $utopia, $request, $response;
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Database\Document;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
@@ -10,6 +11,7 @@ use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Storage\Validator\File;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
App::get('/v1/mock/tests/foo')
|
||||
->desc('Get Foo')
|
||||
@@ -205,7 +207,7 @@ App::get('/v1/mock/tests/general/download')
|
||||
->label('sdk.mock', true)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
|
||||
$response
|
||||
->setContentType('text/plain')
|
||||
@@ -236,72 +238,72 @@ App::post('/v1/mock/tests/general/upload')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->action(function ($x, $y, $z, $file, $request, $response) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Utopia\Swoole\Response $response */
|
||||
|
||||
$file = $request->getFiles('file');
|
||||
|
||||
$contentRange = $request->getHeader('content-range');
|
||||
|
||||
$chunkSize = 5*1024*1024; // 5MB
|
||||
|
||||
if(!empty($contentRange)) {
|
||||
$start = $request->getContentRangeStart();
|
||||
$end = $request->getContentRangeEnd();
|
||||
$size = $request->getContentRangeSize();
|
||||
$id = $request->getHeader('x-appwrite-id', '');
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'] : [$file['size']];
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size'];
|
||||
|
||||
if(is_null($start) || is_null($end) || is_null($size)) {
|
||||
throw new Exception('Invalid content-range header', 400);
|
||||
throw new Exception('Invalid content-range header', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if($start > $end || $end > $size) {
|
||||
throw new Exception('Invalid content-range header', 400);
|
||||
throw new Exception('Invalid content-range header', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if($start === 0 && !empty($id)) {
|
||||
throw new Exception('First chunked request cannot have id header', 400);
|
||||
throw new Exception('First chunked request cannot have id header', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if($start !== 0 && $id !== 'newfileid') {
|
||||
throw new Exception('All chunked request must have id header (except first)', 400);
|
||||
throw new Exception('All chunked request must have id header (except first)', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if($end !== $size && $end-$start+1 !== 5*1024*1024) {
|
||||
throw new Exception('Chunk size must be 5MB (except last chunk)', 400);
|
||||
if($end !== $size && $end-$start+1 !== $chunkSize) {
|
||||
throw new Exception('Chunk size must be 5MB (except last chunk)', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
foreach ($file['size'] as $i => $sz) {
|
||||
if ($end !== $size && $sz !== 5*1024*1024) {
|
||||
throw new Exception('Wrong chunk size', 400);
|
||||
}
|
||||
|
||||
if($sz > 5*1024*1024) {
|
||||
throw new Exception('Chunk size must be 5MB or less', 400);
|
||||
}
|
||||
if ($end !== $size && $file['size'] !== $chunkSize) {
|
||||
throw new Exception('Wrong chunk size', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if($file['size'] > $chunkSize) {
|
||||
throw new Exception('Chunk size must be 5MB or less', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if($end !== $size) {
|
||||
$response->json(['$id'=> 'newfileid']);
|
||||
$response->json([
|
||||
'$id'=> 'newfileid',
|
||||
'chunksTotal' => $file['size'] / $chunkSize,
|
||||
'chunksUploaded' => $start / $chunkSize
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$file['tmp_name'] = (\is_array($file['tmp_name'])) ? $file['tmp_name'] : [$file['tmp_name']];
|
||||
$file['name'] = (\is_array($file['name'])) ? $file['name'] : [$file['name']];
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'] : [$file['size']];
|
||||
$file['tmp_name'] = (\is_array($file['tmp_name'])) ? $file['tmp_name'][0] : $file['tmp_name'];
|
||||
$file['name'] = (\is_array($file['name'])) ? $file['name'][0] : $file['name'];
|
||||
$file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size'];
|
||||
|
||||
foreach ($file['name'] as $i => $name) {
|
||||
if ($name !== 'file.png') {
|
||||
throw new Exception('Wrong file name', 400);
|
||||
}
|
||||
if ($file['name'] !== 'file.png') {
|
||||
throw new Exception('Wrong file name', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
foreach ($file['size'] as $i => $size) {
|
||||
if ($size !== 38756) {
|
||||
throw new Exception('Wrong file size', 400);
|
||||
}
|
||||
if ($file['size'] !== 38756) {
|
||||
throw new Exception('Wrong file size', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
foreach ($file['tmp_name'] as $i => $tmpName) {
|
||||
if (\md5(\file_get_contents($tmpName)) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
|
||||
throw new Exception('Wrong file uploaded', 400);
|
||||
}
|
||||
|
||||
if (\md5(\file_get_contents($file['tmp_name'])) !== 'd80e7e6999a3eb2ae0d631a96fe135a4') {
|
||||
throw new Exception('Wrong file uploaded', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -353,10 +355,12 @@ App::get('/v1/mock/tests/general/set-cookie')
|
||||
->label('sdk.response.model', Response::MODEL_MOCK)
|
||||
->label('sdk.mock', true)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
->inject('request')
|
||||
->action(function ($response, $request) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
|
||||
$response->addCookie('cookieName', 'cookieValue', \time() + 31536000, '/', 'localhost', true, true);
|
||||
$response->addCookie('cookieName', 'cookieValue', \time() + 31536000, '/', $request->getHostname(), true, true);
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/get-cookie')
|
||||
@@ -373,10 +377,10 @@ App::get('/v1/mock/tests/general/get-cookie')
|
||||
->label('sdk.mock', true)
|
||||
->inject('request')
|
||||
->action(function ($request) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
|
||||
if ($request->getCookie('cookieName', '') !== 'cookieValue') {
|
||||
throw new Exception('Missing cookie value', 400);
|
||||
throw new Exception('Missing cookie value', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -411,7 +415,7 @@ App::get('/v1/mock/tests/general/400-error')
|
||||
->label('sdk.response.model', Response::MODEL_ERROR)
|
||||
->label('sdk.mock', true)
|
||||
->action(function () {
|
||||
throw new Exception('Mock 400 error', 400);
|
||||
throw new Exception('Mock 400 error', 400, Exception::GENERAL_MOCK);
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/500-error')
|
||||
@@ -427,7 +431,7 @@ App::get('/v1/mock/tests/general/500-error')
|
||||
->label('sdk.response.model', Response::MODEL_ERROR)
|
||||
->label('sdk.mock', true)
|
||||
->action(function () {
|
||||
throw new Exception('Mock 500 error', 500);
|
||||
throw new Exception('Mock 500 error', 500, Exception::GENERAL_MOCK);
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/502-error')
|
||||
@@ -476,26 +480,44 @@ App::get('/v1/mock/tests/general/oauth2/token')
|
||||
->label('docs', false)
|
||||
->label('sdk.mock', true)
|
||||
->param('client_id', '', new Text(100), 'OAuth2 Client ID.')
|
||||
->param('redirect_uri', '', new Host(['localhost']), 'OAuth2 Redirect URI.')
|
||||
->param('client_secret', '', new Text(100), 'OAuth2 scope list.')
|
||||
->param('code', '', new Text(100), 'OAuth2 state.')
|
||||
->param('grant_type', 'authorization_code', new WhiteList(['refresh_token', 'authorization_code']), 'OAuth2 Grant Type.', true)
|
||||
->param('redirect_uri', '', new Host(['localhost']), 'OAuth2 Redirect URI.', true)
|
||||
->param('code', '', new Text(100), 'OAuth2 state.', true)
|
||||
->param('refresh_token', '', new Text(100), 'OAuth2 refresh token.', true)
|
||||
->inject('response')
|
||||
->action(function ($client_id, $redirectURI, $client_secret, $code, $response) {
|
||||
->action(function ($client_id, $client_secret, $grantType, $redirectURI, $code, $refreshToken, $response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
if ($client_id != '1') {
|
||||
throw new Exception('Invalid client ID');
|
||||
throw new Exception('Invalid client ID', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if ($client_secret != '123456') {
|
||||
throw new Exception('Invalid client secret');
|
||||
throw new Exception('Invalid client secret', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
if ($code != 'abcdef') {
|
||||
throw new Exception('Invalid token');
|
||||
}
|
||||
$responseJson = [
|
||||
'access_token' => '123456',
|
||||
'refresh_token' => 'tuvwxyz',
|
||||
'expires_in' => 14400
|
||||
];
|
||||
|
||||
$response->json(['access_token' => '123456']);
|
||||
if($grantType === 'authorization_code') {
|
||||
if ($code !== 'abcdef') {
|
||||
throw new Exception('Invalid token', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
$response->json($responseJson);
|
||||
} else if($grantType === 'refresh_token') {
|
||||
if ($refreshToken !== 'tuvwxyz') {
|
||||
throw new Exception('Invalid refresh token', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
$response->json($responseJson);
|
||||
} else {
|
||||
throw new Exception('Invalid grant type', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
});
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2/user')
|
||||
@@ -509,13 +531,13 @@ App::get('/v1/mock/tests/general/oauth2/user')
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
if ($token != '123456') {
|
||||
throw new Exception('Invalid token');
|
||||
throw new Exception('Invalid token', 400, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
$response->json([
|
||||
'id' => 1,
|
||||
'name' => 'User Name',
|
||||
'email' => 'user@localhost.test',
|
||||
'email' => 'useroauth@localhost.test',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -551,7 +573,7 @@ App::get('/v1/mock/tests/general/oauth2/failure')
|
||||
|
||||
App::shutdown(function($utopia, $response, $request) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$result = [];
|
||||
@@ -560,7 +582,7 @@ App::shutdown(function($utopia, $response, $request) {
|
||||
$tests = (\file_exists($path)) ? \json_decode(\file_get_contents($path), true) : [];
|
||||
|
||||
if (!\is_array($tests)) {
|
||||
throw new Exception('Failed to read results', 500);
|
||||
throw new Exception('Failed to read results', 500, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
$result[$route->getMethod() . ':' . $route->getPath()] = true;
|
||||
@@ -568,7 +590,7 @@ App::shutdown(function($utopia, $response, $request) {
|
||||
$tests = \array_merge($tests, $result);
|
||||
|
||||
if (!\file_put_contents($path, \json_encode($tests), LOCK_EX)) {
|
||||
throw new Exception('Failed to save resutls', 500);
|
||||
throw new Exception('Failed to save results', 500, Exception::GENERAL_MOCK);
|
||||
}
|
||||
|
||||
$response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']), Response::MODEL_MOCK);
|
||||
|
||||