mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge remote-tracking branch 'upstream/feat-database-indexing' into the-executor-poc
This commit is contained in:
@@ -18,7 +18,7 @@ _APP_REDIS_PORT=6379
|
||||
_APP_DB_HOST=mariadb
|
||||
_APP_DB_PORT=3306
|
||||
_APP_DB_SCHEMA=appwrite
|
||||
_APP_DB_USER=user
|
||||
_APP_DB_USER=root
|
||||
_APP_DB_PASS=password
|
||||
_APP_STORAGE_ANTIVIRUS=disabled
|
||||
_APP_STORAGE_ANTIVIRUS_HOST=clamav
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
about: Submit a bug report to help us improve
|
||||
labels: "bug"
|
||||
---
|
||||
|
||||
## 🐛 Bug Report
|
||||
|
||||
(A clear and concise description of what the bug is)
|
||||
|
||||
## Have you spent some time to check if this issue has been raised before?
|
||||
|
||||
(Have you googled for a similar issue or checked our older issues for a similar bug)
|
||||
|
||||
## To Reproduce
|
||||
|
||||
(Write your steps here:)
|
||||
|
||||
## Expected behavior
|
||||
|
||||
<!--
|
||||
How did you expect your project to behave?
|
||||
It’s fine if you’re not sure your understanding is correct.
|
||||
Write down what you thought would happen.
|
||||
-->
|
||||
|
||||
(Write what you thought would happen.)
|
||||
|
||||
## Actual Behavior
|
||||
|
||||
<!--
|
||||
Did something go wrong?
|
||||
Is something broken, or not behaving as you expected?
|
||||
Describe this section in detail, and attach screenshots if possible.
|
||||
Don't only say "it doesn't work"!
|
||||
-->
|
||||
|
||||
(Write what happened. Add screenshots, if applicable.)
|
||||
|
||||
## Your Environment
|
||||
|
||||
<!-- Include as many relevant details about the environment you experienced the bug in -->
|
||||
|
||||
(Write Environment, Operating system and version etc.)
|
||||
@@ -0,0 +1,82 @@
|
||||
name: "🐛 Bug Report"
|
||||
description: "Submit a bug report to help us improve"
|
||||
title: "🐛 Bug Report: "
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out our bug report form 🙏
|
||||
- type: textarea
|
||||
id: steps-to-reproduce
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "👟 Reproduction steps"
|
||||
description: "How do you trigger this bug? Please walk us through it step by step."
|
||||
placeholder: "When I ..."
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "👍 Expected behavior"
|
||||
description: "What did you think would happen?"
|
||||
placeholder: "It should ..."
|
||||
- type: textarea
|
||||
id: actual-behavior
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "👎 Actual Behavior"
|
||||
description: "What did actually happen? Add screenshots, if applicable."
|
||||
placeholder: "It actually ..."
|
||||
- type: dropdown
|
||||
id: appwrite-version
|
||||
attributes:
|
||||
label: "🎲 Appwrite version"
|
||||
description: "What version of Appwrite are you running?"
|
||||
options:
|
||||
- Version 0.10.x
|
||||
- Version 0.9.x
|
||||
- Version 0.8.x
|
||||
- Version 0.7.x
|
||||
- Version 0.6.x
|
||||
- Different version (specify in environment)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: operating-system
|
||||
attributes:
|
||||
label: "💻 Operating system"
|
||||
description: "What OS is your server / device running on?"
|
||||
options:
|
||||
- Linux
|
||||
- MacOS
|
||||
- Windows
|
||||
- Something else
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
validations:
|
||||
required: false
|
||||
attributes:
|
||||
label: "🧱 Your Environment"
|
||||
description: "Is your environment customized in any way?"
|
||||
placeholder: "I use Cloudflare for ..."
|
||||
- type: checkboxes
|
||||
id: no-duplicate-issues
|
||||
attributes:
|
||||
label: "👀 Have you spent some time to check if this issue has been raised before?"
|
||||
description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
|
||||
options:
|
||||
- label: "I checked and didn't find similar issue"
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: read-code-of-conduct
|
||||
attributes:
|
||||
label: "🏢 Have you read the Code of Conduct?"
|
||||
options:
|
||||
- label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
|
||||
required: true
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: 📚 Documentation
|
||||
about: Report an issue related to documentation
|
||||
labels: "documentation"
|
||||
---
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
(A clear and concise description of what the issue is.)
|
||||
|
||||
## Have you spent some time to check if this issue has been raised before?
|
||||
|
||||
(Have you googled for a similar issue or checked our older issues for a similar bug)
|
||||
|
||||
### Have you read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/master/CODE_OF_CONDUCT.md)?
|
||||
|
||||
(Write your answer here.)
|
||||
@@ -0,0 +1,32 @@
|
||||
name: "📚 Documentation"
|
||||
description: "Report an issue related to documentation"
|
||||
title: "📚 Documentation: "
|
||||
labels: [documentation]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to make our documentation better 🙏
|
||||
- type: textarea
|
||||
id: issue-description
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "💭 Description"
|
||||
description: "A clear and concise description of what the issue is."
|
||||
placeholder: "Documentation should not ..."
|
||||
- type: checkboxes
|
||||
id: no-duplicate-issues
|
||||
attributes:
|
||||
label: "👀 Have you spent some time to check if this issue has been raised before?"
|
||||
description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
|
||||
options:
|
||||
- label: "I checked and didn't find similar issue"
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: read-code-of-conduct
|
||||
attributes:
|
||||
label: "🏢 Have you read the Code of Conduct?"
|
||||
options:
|
||||
- label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
|
||||
required: true
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
name: 🚀 Feature
|
||||
about: Submit a proposal for a new feature
|
||||
labels: "feature"
|
||||
---
|
||||
|
||||
## 🚀 Feature
|
||||
|
||||
(A clear and concise description of what the feature is.)
|
||||
|
||||
## Have you spent some time to check if this issue has been raised before?
|
||||
|
||||
(Have you googled for a similar issue or checked our older issues for a similar bug)
|
||||
|
||||
### Have you read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/master/CODE_OF_CONDUCT.md)?
|
||||
|
||||
(Write your answer here.)
|
||||
|
||||
## Pitch
|
||||
|
||||
(Please explain why this feature should be implemented and how it would be used. Add examples, if applicable.)
|
||||
@@ -0,0 +1,40 @@
|
||||
name: 🚀 Feature
|
||||
description: "Submit a proposal for a new feature"
|
||||
title: "🚀 Feature: "
|
||||
labels: [feature]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out our feature request form 🙏
|
||||
- type: textarea
|
||||
id: feature-description
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "🔖 Feature description"
|
||||
description: "A clear and concise description of what the feature is."
|
||||
placeholder: "You should add ..."
|
||||
- type: textarea
|
||||
id: pitch
|
||||
validations:
|
||||
required: true
|
||||
attributes:
|
||||
label: "🎤 Pitch"
|
||||
description: "Please explain why this feature should be implemented and how it would be used. Add examples, if applicable."
|
||||
placeholder: "In my use-case, ..."
|
||||
- type: checkboxes
|
||||
id: no-duplicate-issues
|
||||
attributes:
|
||||
label: "👀 Have you spent some time to check if this issue has been raised before?"
|
||||
description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
|
||||
options:
|
||||
- label: "I checked and didn't find similar issue"
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: read-code-of-conduct
|
||||
attributes:
|
||||
label: "🏢 Have you read the Code of Conduct?"
|
||||
options:
|
||||
- label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
|
||||
required: true
|
||||
+40
-5
@@ -6,6 +6,9 @@ arch:
|
||||
|
||||
os: linux
|
||||
|
||||
vm:
|
||||
size: large
|
||||
|
||||
language: shell
|
||||
|
||||
notifications:
|
||||
@@ -13,33 +16,65 @@ notifications:
|
||||
- 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
|
||||
- docker buildx create --use
|
||||
- chmod -R u+x ./.travis-ci
|
||||
- export COMPOSE_INTERACTIVE_NO_CLI=1
|
||||
# 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 up -d --build
|
||||
- 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 ps -a
|
||||
# Tests should fail if any container is in exited status
|
||||
- ALL_UP=`docker ps -aq --filter "status=exited"`
|
||||
- >
|
||||
if [[ "$ALL_UP" != "" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
- docker-compose logs appwrite
|
||||
- docker-compose logs mariadb
|
||||
- docker-compose logs appwrite-worker-functions
|
||||
- docker-compose exec appwrite doctor
|
||||
- docker-compose exec appwrite vars
|
||||
- docker-compose exec appwrite test --debug
|
||||
- docker-compose logs appwrite
|
||||
|
||||
after_script:
|
||||
# travis re-uses their build nodes so clean them up
|
||||
- docker buildx rm travis_builder
|
||||
|
||||
after_failure:
|
||||
- docker-compose logs appwrite
|
||||
|
||||
+20
-1
@@ -1,6 +1,25 @@
|
||||
# Unreleased Version 0.11.0
|
||||
|
||||
# Unreleased Version 1.1.0
|
||||
- Added ability to create syncronous function executions
|
||||
- Introduced new execution model for functions
|
||||
|
||||
# Version 1.0.0
|
||||
|
||||
## Features
|
||||
|
||||
- Grouped auth related attributes in project collection. Introduced new attribute `auths` and removed all attributes related to auth methods and `usersAuthLimit` as well, all these are grouped under `auths` attribute
|
||||
- Grouped oAuth related attributes in project collection. Introduced new attribute `providers` and removed all attributes related to OAuth2 providers. All OAuth2 attributes are grouped under `providers`
|
||||
- Project model changed, `userAuth<AuthMethod>` => `auth<AuthMethod>` example `userAuthEmailPassword` => `authEmailPassword`, also `userOauth2<Provider>...` => `provider<Provider>...` example `userOauth2GithubAppid` => `providerGithubAppid`
|
||||
# Version 0.10.4
|
||||
|
||||
## Bugs
|
||||
- Fixed another memory leak in realtime service (#1627)
|
||||
|
||||
# Version 0.10.3
|
||||
|
||||
## 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
|
||||
|
||||
@@ -284,6 +284,17 @@ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
|
||||
|
||||
The Runtimes for all supported cloud functions (multicore builds) can be found at the [appwrite/php-runtimes](https://github.com/appwrite/php-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/0.10.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`
|
||||
|
||||
## Debug
|
||||
|
||||
Appwrite uses [yasd](https://github.com/swoole/yasd) debugger, which can be made available during build of Appwrite. You can connect to the debugger using VS Code [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension or if you are in PHP Storm you don't need any plugin. Below are the settings required for remote debugger connection.
|
||||
|
||||
+57
-36
@@ -1,4 +1,4 @@
|
||||
FROM composer:2.0 as step0
|
||||
FROM composer:2.0 as composer
|
||||
|
||||
ARG TESTING=false
|
||||
ENV TESTING=$TESTING
|
||||
@@ -12,12 +12,13 @@ RUN composer update --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 step1
|
||||
FROM php:8.0-cli-alpine as compile
|
||||
|
||||
ARG DEBUG=false
|
||||
ENV DEBUG=$DEBUG
|
||||
|
||||
ENV PHP_REDIS_VERSION=5.3.4 \
|
||||
PHP_MONGODB_VERSION=1.9.1 \
|
||||
PHP_SWOOLE_VERSION=v4.7.0 \
|
||||
PHP_IMAGICK_VERSION=3.5.1 \
|
||||
PHP_YAML_VERSION=2.2.1 \
|
||||
@@ -41,43 +42,24 @@ RUN \
|
||||
|
||||
RUN docker-php-ext-install sockets
|
||||
|
||||
FROM compile AS redis
|
||||
RUN \
|
||||
# Redis Extension
|
||||
git clone --depth 1 --branch $PHP_REDIS_VERSION https://github.com/phpredis/phpredis.git && \
|
||||
cd phpredis && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## Swoole Extension
|
||||
make && make install
|
||||
|
||||
## Swoole Extension
|
||||
FROM compile AS swoole
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_SWOOLE_VERSION https://github.com/swoole/swoole-src.git && \
|
||||
cd swoole-src && \
|
||||
phpize && \
|
||||
./configure --enable-sockets --enable-http2 --enable-openssl && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## Imagick Extension
|
||||
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/imagick/imagick && \
|
||||
cd imagick && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## YAML Extension
|
||||
git clone --depth 1 --branch $PHP_YAML_VERSION https://github.com/php/pecl-file_formats-yaml && \
|
||||
cd pecl-file_formats-yaml && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd .. && \
|
||||
## Maxminddb extension
|
||||
git clone --depth 1 --branch $PHP_MAXMINDDB_VERSION https://github.com/maxmind/MaxMind-DB-Reader-php.git && \
|
||||
cd MaxMind-DB-Reader-php && \
|
||||
cd ext && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install && \
|
||||
cd ../..
|
||||
cd ..
|
||||
|
||||
## Swoole Debugger setup
|
||||
RUN if [ "$DEBUG" == "true" ]; then \
|
||||
@@ -91,6 +73,44 @@ RUN if [ "$DEBUG" == "true" ]; then \
|
||||
cd ..;\
|
||||
fi
|
||||
|
||||
## Imagick Extension
|
||||
FROM compile AS imagick
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_IMAGICK_VERSION https://github.com/imagick/imagick && \
|
||||
cd imagick && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
## YAML Extension
|
||||
FROM compile AS yaml
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_YAML_VERSION https://github.com/php/pecl-file_formats-yaml && \
|
||||
cd pecl-file_formats-yaml && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
## Maxminddb extension
|
||||
FROM compile AS maxmind
|
||||
RUN \
|
||||
git clone --depth 1 --branch $PHP_MAXMINDDB_VERSION https://github.com/maxmind/MaxMind-DB-Reader-php.git && \
|
||||
cd MaxMind-DB-Reader-php && \
|
||||
cd ext && \
|
||||
phpize && \
|
||||
./configure && \
|
||||
make && make install
|
||||
|
||||
# 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-cli-alpine as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
@@ -186,12 +206,13 @@ RUN \
|
||||
|
||||
WORKDIR /usr/src/code
|
||||
|
||||
COPY --from=step0 /usr/local/src/vendor /usr/src/code/vendor
|
||||
COPY --from=step1 /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=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/imagick.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/maxminddb.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/
|
||||
COPY --from=composer /usr/local/src/vendor /usr/src/code/vendor
|
||||
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
|
||||
@@ -217,6 +238,7 @@ 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 && \
|
||||
@@ -227,11 +249,10 @@ RUN chmod +x /usr/local/bin/doctor && \
|
||||
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-mails && \
|
||||
chmod +x /usr/local/bin/worker-tasks && \
|
||||
chmod +x /usr/local/bin/worker-usage && \
|
||||
chmod +x /usr/local/bin/worker-webhooks
|
||||
|
||||
# Letsencrypt Permissions
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<br />
|
||||
</p>
|
||||
|
||||
<!--[](CONTRIBUTING.md)-->
|
||||
[](https://hacktoberfest.appwrite.io)
|
||||
[](https://appwrite.io/discord)
|
||||
[](https://hub.docker.com/r/appwrite/appwrite)
|
||||
[](https://travis-ci.com/appwrite/appwrite)
|
||||
@@ -39,6 +39,7 @@ Table of Contents:
|
||||
- [SDKs](#sdks)
|
||||
- [Client](#client)
|
||||
- [Server](#server)
|
||||
- [Community](#community)
|
||||
- [Contributing](#contributing)
|
||||
- [Security](#security)
|
||||
- [Follow Us](#follow-us)
|
||||
@@ -57,7 +58,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.10.2
|
||||
appwrite/appwrite:0.10.4
|
||||
```
|
||||
|
||||
### Windows
|
||||
@@ -69,7 +70,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.10.2
|
||||
appwrite/appwrite:0.10.4
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
@@ -79,7 +80,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.10.2
|
||||
appwrite/appwrite:0.10.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.
|
||||
@@ -97,9 +98,9 @@ Getting started with Appwrite is as easy as creating a new project, choosing you
|
||||
|
||||
* [Getting Started for Web](https://appwrite.io/docs/getting-started-for-web)
|
||||
* [Getting Started for Flutter](https://appwrite.io/docs/getting-started-for-flutter)
|
||||
* [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 Android (Coming soon...)
|
||||
* Getting Started for iOS (Coming soon...)
|
||||
|
||||
### Services
|
||||
@@ -134,6 +135,9 @@ Below is a list of currently supported platforms and languages. If you wish to h
|
||||
* ✅ [Kotlin](https://github.com/appwrite/sdk-for-kotlin) - **Beta** (Maintained by the Appwrite Team)
|
||||
* ✅ [.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/))
|
||||
|
||||
Looking for more SDKs? - Help us by contributing a pull request to our [SDK Generator](https://github.com/appwrite/sdk-generator)!
|
||||
|
||||
## Contributing
|
||||
@@ -148,7 +152,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/) 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_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.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/workers.php';
|
||||
require_once __DIR__.'/init.php';
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\CLI;
|
||||
@@ -15,6 +15,7 @@ include 'tasks/migrate.php';
|
||||
include 'tasks/sdks.php';
|
||||
include 'tasks/ssl.php';
|
||||
include 'tasks/vars.php';
|
||||
include 'tasks/usage.php';
|
||||
|
||||
$cli
|
||||
->task('version')
|
||||
|
||||
+5
-6
@@ -5,7 +5,7 @@
|
||||
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',
|
||||
'enabled' => true,
|
||||
@@ -19,30 +19,29 @@ return [
|
||||
],
|
||||
'anonymous' => [
|
||||
'name' => 'Anonymous',
|
||||
'key' => 'usersAuthAnonymous',
|
||||
'key' => 'anonymous',
|
||||
'icon' => '/images/users/anonymous.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#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',
|
||||
'enabled' => true,
|
||||
],
|
||||
'jwt' => [
|
||||
'name' => 'JWT',
|
||||
'key' => 'usersAuthJWT',
|
||||
'key' => 'JWT',
|
||||
'icon' => '/images/users/jwt.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreateJWT',
|
||||
'enabled' => true,
|
||||
],
|
||||
'phone' => [
|
||||
'name' => 'Phone',
|
||||
'key' => 'usersAuthPhone',
|
||||
'key' => 'phone',
|
||||
'icon' => '/images/users/phone.png',
|
||||
'docs' => 'https://appwrite.io/docs/client/account?sdk=web#accountCreatePhoneSession',
|
||||
'docs' => '',
|
||||
'enabled' => false,
|
||||
],
|
||||
|
||||
+20
-184
@@ -11,7 +11,7 @@ $collections = [
|
||||
'console' => [
|
||||
'$id' => 'console',
|
||||
'$collection' => 'projects',
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Appwrite',
|
||||
'description' => 'Appwrite core engine',
|
||||
'logo' => '',
|
||||
@@ -51,7 +51,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_COLLECTIONS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Collections',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -106,7 +106,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_RULES => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Collections Rule',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -186,7 +186,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_USERS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_USERS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'User',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -212,7 +212,7 @@ $collections = [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Status',
|
||||
'key' => 'status',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'type' => Database::SYSTEM_VAR_TYPE_BOOLEAN,
|
||||
'default' => '',
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
@@ -307,7 +307,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_SESSIONS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_SESSIONS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Session',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -505,7 +505,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_TOKENS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_TOKENS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Token',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -568,7 +568,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_MEMBERSHIPS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Membership',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -640,7 +640,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_TEAMS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_TEAMS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Team',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -676,7 +676,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_PROJECTS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_PROJECTS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Project',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -807,16 +807,6 @@ $collections = [
|
||||
'array' => true,
|
||||
'list' => [Database::SYSTEM_COLLECTION_KEYS],
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Tasks',
|
||||
'key' => 'tasks',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_DOCUMENT,
|
||||
'default' => [],
|
||||
'required' => false,
|
||||
'array' => true,
|
||||
'list' => [Database::SYSTEM_COLLECTION_TASKS],
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Platforms',
|
||||
@@ -842,7 +832,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_WEBHOOKS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_WEBHOOKS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Webhook',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -906,7 +896,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_KEYS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_KEYS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Key',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -939,164 +929,10 @@ $collections = [
|
||||
],
|
||||
],
|
||||
],
|
||||
Database::SYSTEM_COLLECTION_TASKS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_TASKS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'name' => 'Task',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Name',
|
||||
'key' => 'name',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => null,
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Status',
|
||||
'key' => 'status',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Updated',
|
||||
'key' => 'updated',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Schedule',
|
||||
'key' => 'schedule',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Previous',
|
||||
'key' => 'previous',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Next',
|
||||
'key' => 'next',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Duration',
|
||||
'key' => 'duration',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Delay',
|
||||
'key' => 'delay',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Security',
|
||||
'key' => 'security',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_BOOLEAN,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'HTTP Method',
|
||||
'key' => 'httpMethod',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'HTTP URL',
|
||||
'key' => 'httpUrl',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'HTTP Headers',
|
||||
'key' => 'httpHeaders',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => null,
|
||||
'required' => false,
|
||||
'array' => true,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'HTTP User',
|
||||
'key' => 'httpUser',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'HTTP Password',
|
||||
'key' => 'httpPass',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
'filter' => ['encrypt'],
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Log',
|
||||
'key' => 'log',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_TEXT,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$collection' => Database::SYSTEM_COLLECTION_RULES,
|
||||
'label' => 'Failures',
|
||||
'key' => 'failures',
|
||||
'type' => Database::SYSTEM_VAR_TYPE_NUMERIC,
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'array' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
Database::SYSTEM_COLLECTION_PLATFORMS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_PLATFORMS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Platform',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1168,7 +1004,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_DOMAINS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_DOMAINS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Domains',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1231,7 +1067,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_CERTIFICATES => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_CERTIFICATES,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Certificates',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1303,7 +1139,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_FILES => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_FILES,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'File',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1447,7 +1283,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_FUNCTIONS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_FUNCTIONS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Functions',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1574,7 +1410,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_TAGS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_TAGS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Tags',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1664,7 +1500,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_EXECUTIONS => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_EXECUTIONS,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Executions',
|
||||
'structure' => true,
|
||||
'rules' => [
|
||||
@@ -1787,7 +1623,7 @@ $collections = [
|
||||
Database::SYSTEM_COLLECTION_RESERVED => [
|
||||
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
|
||||
'$id' => Database::SYSTEM_COLLECTION_RESERVED,
|
||||
'$permissions' => ['read' => ['*']],
|
||||
'$permissions' => ['read' => ['role:all']],
|
||||
'name' => 'Reserved',
|
||||
'structure' => true,
|
||||
],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
@@ -82,6 +97,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,
|
||||
|
||||
@@ -5,10 +5,12 @@ return [
|
||||
'ar', // Arabic
|
||||
'be', // Belarusian
|
||||
'bg', // Bulgarian
|
||||
'bh', // Bihari
|
||||
'bn', // Bengali
|
||||
'bs', //Bosnian
|
||||
'bs', // Bosnian
|
||||
'ca', // Catalan
|
||||
'cs', // Czech
|
||||
'da', // Danish
|
||||
'de', // German
|
||||
'en', // English
|
||||
'es', // Spanish
|
||||
@@ -17,9 +19,10 @@ return [
|
||||
'fo', // Faroese
|
||||
'fr', // French
|
||||
'el', // Greek
|
||||
'gu', //Gujrati
|
||||
'gu', // Gujrati
|
||||
'he', // Hebrew
|
||||
'hi', // Hindi
|
||||
'hi', // Hindi,
|
||||
'hr', // Croatian
|
||||
'hu', // Hungarian
|
||||
'hy', // Armenian
|
||||
'id', // Indonesian
|
||||
@@ -30,6 +33,7 @@ return [
|
||||
'kn', // Kannada
|
||||
'km', // Khmer
|
||||
'ko', // Korean
|
||||
'lb', // Luxembourgish
|
||||
'lt', // Lithuanian
|
||||
'ml', // Malayalam
|
||||
'mr', // Marathi
|
||||
@@ -42,10 +46,12 @@ return [
|
||||
'pl', // Polish
|
||||
'pt-br', // Portuguese - Brazil
|
||||
'pt-pt', // Portuguese - Portugal
|
||||
'pa', //Punjabi
|
||||
'pa', // Punjabi
|
||||
'ro', // Romanian
|
||||
'ru', // Russian
|
||||
'sa', //Sanskrit
|
||||
'si', // Sinhala
|
||||
'sk', // Slovakia
|
||||
'sl', // Slovenian
|
||||
'sq', // Albanian
|
||||
'sv', // Swedish
|
||||
@@ -53,7 +59,7 @@ return [
|
||||
'th', // Thai
|
||||
'tr', // Turkish
|
||||
'uk', // Ukrainian
|
||||
'ur', //Urdu
|
||||
'ur', // Urdu
|
||||
'vi', // Vietnamese
|
||||
'zh-cn', // Chinese - China
|
||||
'zh-tw', // Chinese - Taiwan
|
||||
|
||||
@@ -291,7 +291,7 @@ return [
|
||||
[
|
||||
"code" => "hi",
|
||||
"name" => "Hindi",
|
||||
"nativeName" => "हिन्दी"
|
||||
"nativeName" => "हिन्दी / हिंदी "
|
||||
],
|
||||
[
|
||||
"code" => "ho",
|
||||
@@ -706,7 +706,7 @@ return [
|
||||
[
|
||||
"code" => "sd",
|
||||
"name" => "Sindhi",
|
||||
"nativeName" => "सिनधि"
|
||||
"nativeName" => "सिन्धी / सिंधी "
|
||||
],
|
||||
[
|
||||
"code" => "se",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ar",
|
||||
"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.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}} ارسل لك دعوة لتكون عضوا بفريق {{team}} في {{project}}",
|
||||
"emails.invitation.footer": "اذا كنت غير مهتم، يمكنك تجاهل هذه الرسالة",
|
||||
"emails.invitation.thanks": "شكرا",
|
||||
"emails.invitation.signature": "فريق {{project}}",
|
||||
"locale.country.unknown": "مجهول",
|
||||
"countries.af": "أفغانستان",
|
||||
"countries.ao": "أنغولا",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "be",
|
||||
"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.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}} хацеў запрасіць вас стаць членам каманды {{team}} у {{project}}.",
|
||||
"emails.invitation.footer": "Калі вам гэта не цікава, вы можаце праігнараваць гэтае паведамленне.",
|
||||
"emails.invitation.thanks": "Дзякуем",
|
||||
"emails.invitation.signature": "каманда {{project}}",
|
||||
"locale.country.unknown": "Невядомы",
|
||||
"countries.af": "Афганістан",
|
||||
"countries.ao": "Ангола",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Паўночная Амерыка",
|
||||
"continents.oc": "Акіянія",
|
||||
"continents.sa": "Паўднёвая Амерыка"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"बुद्धिमान होइत क कला ई जाने क कला अछि जे की अनदेखा कर्मा चाहि| \"",
|
||||
"settings.locale": "bh",
|
||||
"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": "पासवर्ड बदल क लेल दिहल गइल लिंक फॉलो करें|",
|
||||
"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": "कांगो लोकतान्त्रिक गणराज्य",
|
||||
"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": "दक्षिण अमेरिका"
|
||||
}
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ca",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Equip",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verificació del compte",
|
||||
"emails.verification.hello": "Hola {{name}}",
|
||||
"emails.verification.body": "Accedeix a aquest enllaç per tal de verificar la teva adreça electrònica.",
|
||||
"emails.verification.footer": "Si no has sol·licitat la verificació d'aquesta adreça electrònica, pots ignorar aquest missatge.",
|
||||
"emails.verification.thanks": "Gràcies",
|
||||
"emails.verification.signature": "Equip {{project}}",
|
||||
"emails.magicSession.subject": "Entrar",
|
||||
"emails.magicSession.hello": "Hola,",
|
||||
"emails.magicSession.body": "Accedeix a aquest enllaç per a entrar.",
|
||||
"emails.magicSession.footer": "Si no has sol·licitat entrar amb aquesta adreça electrònica, pots ignorar aquest missatge.",
|
||||
"emails.magicSession.thanks": "Gràcies",
|
||||
"emails.magicSession.signature": "Equip {{project}}",
|
||||
"emails.recovery.subject": "Reinicialitzar contrasenya",
|
||||
"emails.recovery.hello": "Hola {{name}}",
|
||||
"emails.recovery.body": "Accedeix a aquest enllaç per a reinicialitzar la teva contrasenya de {{project}}.",
|
||||
"emails.recovery.footer": "Si no has sol·licitat reinicialitzar la teva contrasenya, pots ignorar aquest missatge.",
|
||||
"emails.recovery.thanks": "Gràcies",
|
||||
"emails.recovery.signature": "Equip {{project}}",
|
||||
"emails.invitation.subject": "Invitació a l'equip %s a s%",
|
||||
"emails.invitation.hello": "Hola",
|
||||
"emails.invitation.body": "Aquest correu se t'ha enviat perquè {{owner}} vol convidar-te a formar part de l'equip {{team}} al {{project}}.",
|
||||
"emails.invitation.footer": "Si no és del teu interès, pots ignorar aquest missatge.",
|
||||
"emails.invitation.thanks": "Gràcies",
|
||||
"emails.invitation.signature": "Equip {{project}}",
|
||||
"locale.country.unknown": "Desconegut",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
@@ -29,7 +35,7 @@
|
||||
"countries.ae": "Unió dels Emirats Àrabs Units",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armènia",
|
||||
"countries.ag": "Antigua o Barbuda",
|
||||
"countries.ag": "Antigua i Barbuda",
|
||||
"countries.au": "Austràlia",
|
||||
"countries.at": "Àustria",
|
||||
"countries.az": "Azerbaidjan",
|
||||
@@ -38,7 +44,7 @@
|
||||
"countries.bj": "Benín",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangla Desh",
|
||||
"countries.bg": "Bulgaria",
|
||||
"countries.bg": "Bulgària",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bòsnia i Hercegovina",
|
||||
@@ -107,7 +113,7 @@
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Itàlia",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordà",
|
||||
"countries.jo": "Jordània",
|
||||
"countries.jp": "Japó",
|
||||
"countries.kz": "Kazakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
@@ -121,7 +127,7 @@
|
||||
"countries.lb": "Líban",
|
||||
"countries.lr": "Libèria",
|
||||
"countries.ly": "Líbia",
|
||||
"countries.lc": "Santa Llúcia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesoto",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"Kunsten at være klog er kunsten at vide, hvad man skal overse.\"",
|
||||
"settings.locale": "da",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Konto Verifikation",
|
||||
"emails.verification.hello": "Hej {{name}}",
|
||||
"emails.verification.body": "Følg dette link, for at verificere din email adresse.",
|
||||
"emails.verification.footer": "Hvis du ikke har bedt om at verificere denne adresse, ignorer venligst denne besked.",
|
||||
"emails.verification.thanks": "Tak",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hej,",
|
||||
"emails.magicSession.body": "Følg dette link for at logge ind.",
|
||||
"emails.magicSession.footer": "Hvis du ikke har bedt om at logge ind med denne email, ignorer venligst denne besked.",
|
||||
"emails.magicSession.thanks": "Tak",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Nulstil Password",
|
||||
"emails.recovery.hello": "Hej {{name}}",
|
||||
"emails.recovery.body": "Følg dette link for at nulstille koden til {{project}}.",
|
||||
"emails.recovery.footer": "Hvis du ikke har bedt om at nulstille dit password, ignorer venligst denne besked.",
|
||||
"emails.recovery.thanks": "Tak",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitation til %s Team på %s",
|
||||
"emails.invitation.hello": "Hej",
|
||||
"emails.invitation.body": "Denne mail blev sendt til dig, fordi {{owner}} vil invitere dig til at blive medlem af {{team}} teamet på {{project}}.",
|
||||
"emails.invitation.footer": "Hvis du ikke er interesseret, ignorer venligst denne besked.",
|
||||
"emails.invitation.thanks": "Tak",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Ukendt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albanien",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Forenede Arabiske Emirater",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenien",
|
||||
"countries.ag": "Antigua and Barbuda",
|
||||
"countries.au": "Australien",
|
||||
"countries.at": "Østrig",
|
||||
"countries.az": "Aserbajdsjan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgien",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesh",
|
||||
"countries.bg": "Bulgarien",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnien-Hercegovina",
|
||||
"countries.by": "Hviderusland",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivia",
|
||||
"countries.br": "Brasilien",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Den Centralafrikanske Republik",
|
||||
"countries.ca": "Canada",
|
||||
"countries.ch": "Schweiz",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Kina",
|
||||
"countries.ci": "Elfenbenskysten",
|
||||
"countries.cm": "Cameroun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republikken Congo",
|
||||
"countries.co": "Colombia",
|
||||
"countries.km": "Comorerne",
|
||||
"countries.cv": "Kap Verde",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Cuba",
|
||||
"countries.cy": "Cypern",
|
||||
"countries.cz": "Tjekkiet",
|
||||
"countries.de": "Tyskland",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Danmark",
|
||||
"countries.do": "Dominikanske Republik",
|
||||
"countries.dz": "Algeriet",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Egypten",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spainen",
|
||||
"countries.ee": "Estland",
|
||||
"countries.et": "Etiopien",
|
||||
"countries.fi": "Finland",
|
||||
"countries.fj": "Fiji",
|
||||
"countries.fr": "Frankrig",
|
||||
"countries.fm": "Mikronesien",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Storbritannien",
|
||||
"countries.ge": "Georgien",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Ækvatorialguinea",
|
||||
"countries.gr": "Grækenland",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Ungarn",
|
||||
"countries.id": "Indonesien",
|
||||
"countries.in": "Indien",
|
||||
"countries.ie": "Irland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italen",
|
||||
"countries.jm": "Jamaica",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kasakhstan",
|
||||
"countries.ke": "Kenya",
|
||||
"countries.kg": "Kirgisistan",
|
||||
"countries.kh": "Cambodja",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts og Nevis",
|
||||
"countries.kr": "Sydkorea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libyen",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litauen",
|
||||
"countries.lu": "Luxembourg",
|
||||
"countries.lv": "Letland",
|
||||
"countries.ma": "Marokko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldova",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldiverne",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mh": "Marshalløerne",
|
||||
"countries.mk": "Makedonien",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongoliet",
|
||||
"countries.mz": "Mozambique",
|
||||
"countries.mr": "Mauritanien",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysia",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Holland",
|
||||
"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": "Filippinerne",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Ny Guinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nordkorea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Qatar",
|
||||
"countries.ro": "Rumænien",
|
||||
"countries.ru": "Rusland",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudi Arabien",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapore",
|
||||
"countries.sb": "Salomonøerne",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbien",
|
||||
"countries.ss": "Sydsudan",
|
||||
"countries.st": "Sao Tome og Principe",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovakiet",
|
||||
"countries.si": "Slovenien",
|
||||
"countries.se": "Sverige",
|
||||
"countries.sz": "Swaziland",
|
||||
"countries.sc": "Seychellerne",
|
||||
"countries.sy": "Syrien",
|
||||
"countries.td": "Tchad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tadsjikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad og Tobago",
|
||||
"countries.tn": "Tunisien",
|
||||
"countries.tr": "Tyrkiet",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "Amerikas Forenede Stater",
|
||||
"countries.uz": "Usbekistan",
|
||||
"countries.va": "Vatikanet",
|
||||
"countries.vc": "Saint Vincent og Grenadinerne",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "Sydafrika",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktis",
|
||||
"continents.as": "Asien",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Nordamerica",
|
||||
"continents.oc": "Oceanien",
|
||||
"continents.sa": "Sydamerica"
|
||||
}
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "de",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Kontoverifizierung",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Folge diesem Link, um deine E-Mail-Adresse zu bestätigen.",
|
||||
"emails.verification.footer": "Solltest du keine Verifizierung dieser E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.",
|
||||
"emails.verification.thanks": "Danke",
|
||||
"emails.verification.signature": "{{project}}-Team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Folge diesem Link, um dich einzuloggen.",
|
||||
"emails.magicSession.footer": "Solltest du keinen Login für diese E-Mail-Adresse angefordert haben, kannst du diese Nachricht ignorieren.",
|
||||
"emails.magicSession.thanks": "Danke",
|
||||
"emails.magicSession.signature": "{{project}}-Team",
|
||||
"emails.recovery.subject": "Kennwort zurücksetzen",
|
||||
"emails.recovery.hello": "Hallo {{name}}",
|
||||
"emails.recovery.body": "Folge diesem Link, um dein {{project}}-Kennwort zurückzusetzen.",
|
||||
"emails.recovery.footer": "Solltest du keine Kennwort-Zurücksetzung angefordert haben, kannst du diese Nachricht ignorieren.",
|
||||
"emails.recovery.thanks": "Danke",
|
||||
"emails.recovery.signature": "{{project}}-Team",
|
||||
"emails.invitation.subject": "Einladung zum %s-Team auf %s",
|
||||
"emails.invitation.hello": "Hello",
|
||||
"emails.invitation.body": "Du erhälst diese E-Mail, weil {{owner}} dich in das Team {{team}} auf {{project}} eingeladen hat.",
|
||||
"emails.invitation.footer": "Wenn du nicht interessiert bist, kannst du diese Nachricht ignorieren.",
|
||||
"emails.invitation.thanks": "Danke",
|
||||
"emails.invitation.signature": "{{project}}-Team",
|
||||
"locale.country.unknown": "Unbekannt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
@@ -135,7 +141,7 @@
|
||||
"countries.mv": "Malediven",
|
||||
"countries.mx": "Mexiko",
|
||||
"countries.mh": "Marshallinseln",
|
||||
"countries.mk": "Mazedonien",
|
||||
"countries.mk": "Nordmazedonien",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
@@ -163,7 +169,7 @@
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Neu-Guinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nord Korea",
|
||||
"countries.kp": "Nordkorea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Katar",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Nordamerika",
|
||||
"continents.oc": "Ozeanien",
|
||||
"continents.sa": "Südamerika"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"Η τέχνη του να είσαι σοφός, είναι η τέχνη να ξέρεις τι πρέπει να παραβλέψεις.\"",
|
||||
"settings.locale": "gr",
|
||||
"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.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": "Ακολουθήστε αυτό το link για να επαληθεύσετε τη δ/νση του email σας",
|
||||
"emails.verification.footer": "Εάν δεν ζητήσατε επαλήθευση αυτής της δ/νσης email, μπορείτε να αγνοήσετε αυτό το μήνυμα",
|
||||
"emails.verification.thanks": "Ευχαριστούμε",
|
||||
"emails.verification.signature": "Η ομάδα του {{project}}",
|
||||
"emails.magicSession.subject": "Είσοδος",
|
||||
"emails.magicSession.hello": "Γεια σου,",
|
||||
"emails.magicSession.body": "Ακολουθήστε αυτό το link για να συνδεθείτε",
|
||||
"emails.magicSession.footer": "Εάν δεν ζητήσατε να συνδεθείτε χρησιμοποιώντας αυτό το email, μπορείτε να αγνοήσετε αυτό το μήνυμα.",
|
||||
"emails.magicSession.thanks": "Ευχαριστούμε",
|
||||
"emails.magicSession.signature": "Η ομάδα του {{project}}",
|
||||
"emails.recovery.subject": "Αλλαγή κωδικού πρόσβασης",
|
||||
"emails.recovery.hello": "Γεια σου {{name}}",
|
||||
"emails.recovery.body": "Ακολουθήστε αυτό το link για να αλλάξετε τον {{project}} κωδικό σας",
|
||||
"emails.recovery.footer": "Εάν δεν ζητήσατε αλλαγή του κωδικού σας πρόσβασης, μπορείτε να αγνοήσετε αυτό το μήνυμα",
|
||||
"emails.recovery.thanks": "Ευχαριστούμε",
|
||||
"emails.recovery.signature": "Η ομάδα του {{project}}",
|
||||
"emails.invitation.subject": "Πρόσκληση στην %s Ομάδα στον %s",
|
||||
"emails.invitation.hello": "Γεια σου",
|
||||
"emails.invitation.body": "Αυτό το email στάλθηκε επειδή ο/η {{owner}} θέλει να σας προσκαλέσει να γίνετε μέλος της ομάδας {{team}} του {{project}}.",
|
||||
"emails.invitation.footer": "Εάν δεν ενδιαφέρεστε, μπορείτε να αγνοήσετε αυτό το μήνυμα.",
|
||||
"emails.invitation.thanks": "Ευχαριστούμε",
|
||||
"emails.invitation.signature": "Η ομάδα του {{project}}",
|
||||
"locale.country.unknown": "Άγνωστο",
|
||||
"countries.af": "Αφγανιστάν",
|
||||
"countries.ao": "Ανγκόλα",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Βόρεια Αμερική",
|
||||
"continents.oc": "Ωκεανία",
|
||||
"continents.sa": "Νότια Αμερική"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "es",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Equipo %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verificación de cuenta",
|
||||
"emails.verification.hello": "Hola {{name}}",
|
||||
"emails.verification.body": "Haz clic en este enlace para verificar tu correo.",
|
||||
"emails.verification.footer": "Si no has solicitado verificar este correo, puedes ignorar este mensaje.",
|
||||
"emails.verification.thanks": "Gracias",
|
||||
"emails.verification.signature": "Equipo de {{project}}",
|
||||
"emails.magicSession.subject": "Inicio de sesión",
|
||||
"emails.magicSession.hello": "Hola,",
|
||||
"emails.magicSession.body": "Haz clic en este enlace para iniciar sesión.",
|
||||
"emails.magicSession.footer": "Si no has solicitado ingresar usando este correo, puedes ignorar este mensaje.",
|
||||
"emails.magicSession.thanks": "Gracias",
|
||||
"emails.magicSession.signature": "Equipo de {{project}}",
|
||||
"emails.recovery.subject": "Restablecer contraseña",
|
||||
"emails.recovery.hello": "Hola {{name}}",
|
||||
"emails.recovery.body": "Haz clic en este enlace para restablecer la contraseña de tu proyecto {{project}}.",
|
||||
"emails.recovery.footer": "Si no has solicitado restablecer la contraseña, puedes ignorar este mensaje.",
|
||||
"emails.recovery.thanks": "Gracias",
|
||||
"emails.recovery.signature": "Equipo de {{project}}",
|
||||
"emails.invitation.subject": "Invitación al equipo %s en %s",
|
||||
"emails.invitation.hello": "Hola",
|
||||
"emails.invitation.body": "Este correo ha sido enviado a petición de {{owner}} quien quiere invitarte a formar parte del equipo {{team}} en el proyecto {{project}}.",
|
||||
"emails.invitation.footer": "Si no estas interesado, puedes ignorar este mensaje.",
|
||||
"emails.invitation.thanks": "Gracias",
|
||||
"emails.invitation.signature": "Equipo de {{project}}",
|
||||
"locale.country.unknown": "Desconocido",
|
||||
"countries.af": "Afganistán",
|
||||
"countries.ao": "Angola",
|
||||
@@ -133,7 +139,7 @@
|
||||
"countries.md": "Moldavia",
|
||||
"countries.mg": "Madagascar",
|
||||
"countries.mv": "Maldivas",
|
||||
"countries.mx": "Mexico",
|
||||
"countries.mx": "México",
|
||||
"countries.mh": "Islas Marshall",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Malí",
|
||||
|
||||
@@ -3,26 +3,32 @@
|
||||
"settings.locale": "fa",
|
||||
"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.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": "تیم {{name}}",
|
||||
"emails.magicSession.subject": "ورود به حساب کاربری",
|
||||
"emails.magicSession.hello": "سلام،",
|
||||
"emails.magicSession.body": "برای ورود به حسابتان پیوند زیر را دنبال کنید.",
|
||||
"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.thanks": "سپاس فراوان",
|
||||
"emails.recovery.signature": "تیم {{name}}",
|
||||
"emails.invitation.subject": "دعوت به تیم %s در %s",
|
||||
"emails.invitation.hello": "سلام",
|
||||
"emails.invitation.body": "این ایمیل برای شما فرستاده شدهاست زیرا {{owner}} میخواهد شما را به تیم {{team}} در پروژهی {{project}} بیفزاید.",
|
||||
"emails.invitation.footer": "اگر علاقه ندارید، میتوانید این پیام را نادیده بگیرید.",
|
||||
"emails.invitation.thanks": "سپاس فراوان",
|
||||
"emails.invitation.signature": "تیم {{name}}",
|
||||
"locale.country.unknown": "ناشناخته",
|
||||
"countries.af": "افقانستان",
|
||||
"countries.af": "افغانستان",
|
||||
"countries.ao": "آنگولا",
|
||||
"countries.al": "آلبانی",
|
||||
"countries.ad": "آندورا",
|
||||
@@ -102,20 +108,20 @@
|
||||
"countries.in": "هند",
|
||||
"countries.ie": "ایرلند",
|
||||
"countries.ir": "ایران",
|
||||
"countries.iq": "عراث",
|
||||
"countries.iq": "عراق",
|
||||
"countries.is": "ایسلند",
|
||||
"countries.il": "اسرائیل",
|
||||
"countries.it": "ایتالیا",
|
||||
"countries.jm": "جاماییکا",
|
||||
"countries.jo": "اردن",
|
||||
"countries.jp": "جاپن",
|
||||
"countries.jp": "ژاپن",
|
||||
"countries.kz": "قزاقستان",
|
||||
"countries.ke": "کنیا",
|
||||
"countries.kg": "قرقیزستان",
|
||||
"countries.kh": "کامبوج",
|
||||
"countries.ki": "کیریباتی",
|
||||
"countries.kn": "سنت کیتس و نویس",
|
||||
"countries.kr": "کرخ جنوبی",
|
||||
"countries.kr": "کره جنوبی",
|
||||
"countries.kw": "کویت",
|
||||
"countries.la": "لائوس",
|
||||
"countries.lb": "لبنان",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "آمریکای شمالی",
|
||||
"continents.oc": "اقیانوسیه",
|
||||
"continents.sa": "آمریکای جنوبی"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"Viisaus merkitsee epäolennaisen ohittamisen taitoa.\"",
|
||||
"settings.locale": "fi",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Tiimi",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "",
|
||||
"locale.country.unknown": "Unknown",
|
||||
"emails.verification.subject": "Tilin vahvistaminen",
|
||||
"emails.verification.hello": "Hei {{name}}",
|
||||
"emails.verification.body": "Vahvista sähköpostiosoitteesi napsauttamalla tätä linkkiä.",
|
||||
"emails.verification.footer": "Voit ohittaa tämän viestin, jos et pyytänyt sähköpostiosoitteen vahvistamista.",
|
||||
"emails.verification.thanks": "Kiitos",
|
||||
"emails.verification.signature": "Projektin {{project}} tiimi",
|
||||
"emails.magicSession.subject": "Sisäänkirjautuminen",
|
||||
"emails.magicSession.hello": "Hei,",
|
||||
"emails.magicSession.body": "Kirjaudu sisään napsauttamalla tätä linkkiä.",
|
||||
"emails.magicSession.footer": "Voit ohittaa tämän viestin, jos et pyytänyt sisäänkirjautumista tällä sähköpostiosoitteella.",
|
||||
"emails.magicSession.thanks": "Kiitos",
|
||||
"emails.magicSession.signature": "Projektin {{project}} tiimi",
|
||||
"emails.recovery.subject": "Salasanan nollaaminen",
|
||||
"emails.recovery.hello": "Hei {{name}}",
|
||||
"emails.recovery.body": "Nollaa projektin {{project}} salasanasi napsauttamalla tätä linkkiä.",
|
||||
"emails.recovery.footer": "Voit ohittaa tämän viestin, jos et pyytänyt salasanasi nollaamista.",
|
||||
"emails.recovery.thanks": "Kiitos",
|
||||
"emails.recovery.signature": "Projektin {{project}} tiimi",
|
||||
"emails.invitation.subject": "Kutsu liittyä tiimiin %s projektissa %s",
|
||||
"emails.invitation.hello": "Hei",
|
||||
"emails.invitation.body": "Saat tämän viestin, koska {{owner}} haluaa kutsua sinut tiimin {{team}} jäseneksi projektissa {{project}}.",
|
||||
"emails.invitation.footer": "Voit ohittaa tämän viestin, jos et halua liittyä tiimiin.",
|
||||
"emails.invitation.thanks": "Kiitos",
|
||||
"emails.invitation.signature": "Projektin {{project}} tiimi",
|
||||
"locale.country.unknown": "Tuntematon",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
@@ -220,7 +226,7 @@
|
||||
"continents.an": "Antarktis",
|
||||
"continents.as": "Aasia",
|
||||
"continents.eu": "Eurooppa",
|
||||
"continents.na": "Pohjois Amerikka",
|
||||
"continents.na": "Pohjois-Amerikka",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "Etelä Amerikka"
|
||||
"continents.sa": "Etelä-Amerikka"
|
||||
}
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "fr",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Équipe %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Vérification du compte",
|
||||
"emails.verification.hello": "Bonjour {{name}}",
|
||||
"emails.verification.body": "Suivez ce lien pour vérifier votre adresse mail.",
|
||||
"emails.verification.footer": "Si vous n'avez pas demandé à vérifier cette adresse mail, vous pouvez ignorer ce message.",
|
||||
"emails.verification.thanks": "Merci",
|
||||
"emails.verification.signature": "Équipe {{project}}",
|
||||
"emails.magicSession.subject": "Connexion",
|
||||
"emails.magicSession.hello": "Bonjour,",
|
||||
"emails.magicSession.body": "Suivez ce lien pour vous connecter.",
|
||||
"emails.magicSession.footer": "Si vous n'avez pas demandé à vous connecter en utilisant cet e-mail, vous pouvez ignorer ce message.",
|
||||
"emails.magicSession.thanks": "Merci",
|
||||
"emails.magicSession.signature": "Réinitialisation du mot de passe",
|
||||
"emails.recovery.subject": "Bonjour {{name}}",
|
||||
"emails.recovery.hello": "Bonjour {{name}}",
|
||||
"emails.recovery.body": "Suivez ce lien pour réinitialiser votre mot de passe de {{projet}}.",
|
||||
"emails.recovery.footer": "Si vous n'avez pas demandé à réinitialiser votre mot de passe, vous pouvez ignorer ce message.",
|
||||
"emails.recovery.thanks": "Merci",
|
||||
"emails.recovery.signature": "Équipe {{project}}",
|
||||
"emails.invitation.subject": "Invitation à l'équipe %s de %s",
|
||||
"emails.invitation.hello": "Bonjour",
|
||||
"emails.invitation.body": "Ce mail vous a été envoyé parce que {{owner}} voulait vous inviter à devenir membre de l'équipe {{team}} de {{project}}.",
|
||||
"emails.invitation.footer": "Si vous n'êtes pas intéressé, vous pouvez ignorer ce message.",
|
||||
"emails.invitation.thanks": "Merci",
|
||||
"emails.invitation.signature": "Équipe {{project}}",
|
||||
"locale.country.unknown": "Inconnu",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -3,25 +3,31 @@
|
||||
"settings.locale": "gu",
|
||||
"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.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": "",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
"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": "અલ્બેનિયા",
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"להיות חכם זה לדעת ממה להתעלם.\"",
|
||||
"settings.locale": "he",
|
||||
"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.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}} רצה להזמין אותך להיות חבר בצוות {{team}} ב-{{project}}.",
|
||||
"emails.invitation.footer": "אם אינך מעוניין, תוכל להתעלם מהודעה זו.",
|
||||
"emails.invitation.thanks": "תודה",
|
||||
"emails.invitation.signature": "צוות {{project}}",
|
||||
"locale.country.unknown": "לא ידוע",
|
||||
"countries.af": "אפגניסטן",
|
||||
"countries.ao": "אנגולה",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "hi",
|
||||
"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.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}} आपको {{team}} टीम का सदस्य बनने के लिए आमंत्रित करना चाहते थे जो {{project}} से जुड़ा है।",
|
||||
"emails.invitation.footer": "यदि यह आपके लिए आवश्यक नहीं है, तो आप इस संदेश को नज़रअंदाज़ कर सकते हैं।",
|
||||
"emails.invitation.thanks": "धन्यवाद",
|
||||
"emails.invitation.signature": "{{project}} टीम",
|
||||
"locale.country.unknown": "अज्ञात",
|
||||
"countries.af": "अफ़ग़ानिस्तान",
|
||||
"countries.ao": "अंगोला",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "उत्तरी अमेरिका",
|
||||
"continents.oc": "ओशिनिया",
|
||||
"continents.sa": "दक्षिण अमेरिका"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"Umjetnost mudrosti je umjetnost znanja o tome što zanemariti.\"",
|
||||
"settings.locale": "hr",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Tim",
|
||||
"emails.verification.subject": "Verifikacija računa",
|
||||
"emails.verification.hello": "Pozdrav {{name}}",
|
||||
"emails.verification.body": "Slijedite ovu poveznicu da biste potvrdili svoju adresu e-pošte.",
|
||||
"emails.verification.footer": "Ukoliko niste zatražili potvrdu ove adrese, možete zanemariti ovu poruku.",
|
||||
"emails.verification.thanks": "Hvala",
|
||||
"emails.verification.signature": "{{project}} tim",
|
||||
"emails.magicSession.subject": "Prijavite se",
|
||||
"emails.magicSession.hello": "Pozdrav,",
|
||||
"emails.magicSession.body": "Slijedite ovu poveznicu za prijavu.",
|
||||
"emails.magicSession.footer": "Ako niste zatražili prijavu putem ove e-pošte, možete zanemariti ovu poruku.",
|
||||
"emails.magicSession.thanks": "Hvala",
|
||||
"emails.magicSession.signature": "{{project}} tim",
|
||||
"emails.recovery.subject": "Ponovno postavljanje lozinke",
|
||||
"emails.recovery.hello": "Pozdrav {{name}}",
|
||||
"emails.recovery.body": "Slijedite ovu poveznicu za ponovno postavljanje {{project}} lozinke.",
|
||||
"emails.recovery.footer": "Ako niste zatražili ponovno postavljanje Vaše lozinke, možete zanemariti ovu poruku.",
|
||||
"emails.recovery.thanks": "Hvala",
|
||||
"emails.recovery.signature": "{{project}} tim",
|
||||
"emails.invitation.subject": "Pozivnica za %s tim na %s",
|
||||
"emails.invitation.hello": "Pozdrav",
|
||||
"emails.invitation.body": "Ova poruka Vam je poslana jer Vas je {{owner}} htio pozvati da postanete član {{team}} tima na {{project}}.",
|
||||
"emails.invitation.footer": "Ukoliko niste zainteresirani, možete zanemariti ovu poruku.",
|
||||
"emails.invitation.thanks": "Hvala",
|
||||
"emails.invitation.signature": "{{project}} tim",
|
||||
"locale.country.unknown": "Nepoznato",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albanija",
|
||||
"countries.ad": "Andora",
|
||||
"countries.ae": "Ujedinjeni Arapski Emirati",
|
||||
"countries.ar": "Argentina",
|
||||
"countries.am": "Armenija",
|
||||
"countries.ag": "Antigva i Barbuda",
|
||||
"countries.au": "Australija",
|
||||
"countries.at": "Austrija",
|
||||
"countries.az": "Azerbajdžan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgija",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladeš",
|
||||
"countries.bg": "Bugarska",
|
||||
"countries.bh": "Bahrein",
|
||||
"countries.bs": "Bahami",
|
||||
"countries.ba": "Bosna i Hercegovina",
|
||||
"countries.by": "Bjelorusija",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivija",
|
||||
"countries.br": "Brazil",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunej",
|
||||
"countries.bt": "Butan",
|
||||
"countries.bw": "Bocvana",
|
||||
"countries.cf": "Srednjoafrička Republika",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Švicarska",
|
||||
"countries.cl": "Čile",
|
||||
"countries.cn": "Kina",
|
||||
"countries.ci": "Obala bjelokosti",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "Demokratska Republika Kongo",
|
||||
"countries.cg": "Republika Kongo",
|
||||
"countries.co": "Kolumbija",
|
||||
"countries.km": "Komori",
|
||||
"countries.cv": "Zelenortska Republika",
|
||||
"countries.cr": "Kostarika",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cipar",
|
||||
"countries.cz": "Češka",
|
||||
"countries.de": "Njemačka",
|
||||
"countries.dj": "Džibuti",
|
||||
"countries.dm": "Dominika",
|
||||
"countries.dk": "Danska",
|
||||
"countries.do": "Dominikanska Republika",
|
||||
"countries.dz": "Alžir",
|
||||
"countries.ec": "Ekvador",
|
||||
"countries.eg": "Egipt",
|
||||
"countries.er": "Eritreja",
|
||||
"countries.es": "Španjolska",
|
||||
"countries.ee": "Estonija",
|
||||
"countries.et": "Etiopija",
|
||||
"countries.fi": "Finska",
|
||||
"countries.fj": "Fidži",
|
||||
"countries.fr": "Francuska",
|
||||
"countries.fm": "Mikronezija",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Ujedinjeno Kraljevstvo",
|
||||
"countries.ge": "Gruzija",
|
||||
"countries.gh": "Gana",
|
||||
"countries.gn": "Gvineja",
|
||||
"countries.gm": "Gambija",
|
||||
"countries.gw": "Gvineja Bisau",
|
||||
"countries.gq": "Ekvatorijalna Gvineja",
|
||||
"countries.gr": "Grčka",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Gvajana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Hrvatska",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Mađarska",
|
||||
"countries.id": "Indonezija",
|
||||
"countries.in": "Indija",
|
||||
"countries.ie": "Irska",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Izrael",
|
||||
"countries.it": "Italija",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kazahstan",
|
||||
"countries.ke": "Kenija",
|
||||
"countries.kg": "Kirgistan",
|
||||
"countries.kh": "Kambodža",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Sveti Kristofor i Nevis",
|
||||
"countries.kr": "Južna Koreja",
|
||||
"countries.kw": "Kuvajt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberija",
|
||||
"countries.ly": "Libija",
|
||||
"countries.lc": "Sveta Lucija",
|
||||
"countries.li": "Lihtenštajn",
|
||||
"countries.lk": "Šri Lanka",
|
||||
"countries.ls": "Lesoto",
|
||||
"countries.lt": "Litva",
|
||||
"countries.lu": "Luksemburg",
|
||||
"countries.lv": "Latvija",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monako",
|
||||
"countries.md": "Moldavija",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldivi",
|
||||
"countries.mx": "Meksiko",
|
||||
"countries.mh": "Maršalovi otoci",
|
||||
"countries.mk": "Sjeverna Makedonija",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Mijanmar",
|
||||
"countries.me": "Crna Gora",
|
||||
"countries.mn": "Mongolija",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauritanija",
|
||||
"countries.mu": "Mauricijus",
|
||||
"countries.mw": "Malavi",
|
||||
"countries.my": "Malezija",
|
||||
"countries.na": "Namibija",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigerija",
|
||||
"countries.ni": "Nikaragva",
|
||||
"countries.nl": "Nizozemska",
|
||||
"countries.no": "Norveška",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Novi Zeland",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipini",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Nova Guineja",
|
||||
"countries.pl": "Poljska",
|
||||
"countries.kp": "Sjeverna Koreja",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paragvaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunjska",
|
||||
"countries.ru": "Rusija",
|
||||
"countries.rw": "Ruanda",
|
||||
"countries.sa": "Saudijska Arabija",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Solomonski otoci",
|
||||
"countries.sl": "Sijera Leone",
|
||||
"countries.sv": "Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalija",
|
||||
"countries.rs": "Srbija",
|
||||
"countries.ss": "Južni Sudan",
|
||||
"countries.st": "Sveti Toma i Prinsipe",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovačka",
|
||||
"countries.si": "Slovenija",
|
||||
"countries.se": "Švedska",
|
||||
"countries.sz": "Esvatini",
|
||||
"countries.sc": "Sejšeli",
|
||||
"countries.sy": "Sirija",
|
||||
"countries.td": "Čad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Tajland",
|
||||
"countries.tj": "Tadžikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad i Tobago",
|
||||
"countries.tn": "Tunis",
|
||||
"countries.tr": "Turska",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzanija",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukrajina",
|
||||
"countries.uy": "Urugvaj",
|
||||
"countries.us": "Sjedinjene Američke Države",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatikan",
|
||||
"countries.vc": "Sveti Vincent i Grenadini",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vijetnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Južnoafrička Republika",
|
||||
"countries.zm": "Zambija",
|
||||
"countries.zw": "Zimbabve",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antartika",
|
||||
"continents.as": "Azija",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Sjeverna Amerika",
|
||||
"continents.oc": "Oceanija",
|
||||
"continents.sa": "Južna Amerika"
|
||||
}
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "id",
|
||||
"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.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": "Ikuti tautan ini untuk memverifikasi alamat email Anda.",
|
||||
"emails.verification.footer": "Jika Anda tidak meminta untuk memverifikasi alamat email ini, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.verification.thanks": "Terima kasih",
|
||||
"emails.verification.signature": "Tim {{project}}",
|
||||
"emails.magicSession.subject": "Masuk",
|
||||
"emails.magicSession.hello": "Hai,",
|
||||
"emails.magicSession.body": "Ikuti tautan ini untuk masuk.",
|
||||
"emails.magicSession.footer": "Jika Anda tidak meminta untuk masuk menggunakan email ini, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.magicSession.thanks": "Terima kasih",
|
||||
"emails.magicSession.signature": "Tim {{project}}",
|
||||
"emails.recovery.subject": "Atur Ulang Kata Sandi",
|
||||
"emails.recovery.hello": "Halo {{name}}",
|
||||
"emails.recovery.body": "Ikuti tautan ini untuk menyetel ulang kata sandi {{project}} Anda.",
|
||||
"emails.recovery.footer": "Jika Anda tidak meminta untuk menyetel ulang kata sandi, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.recovery.thanks": "Terima kasih",
|
||||
"emails.recovery.signature": "Tim {{project}}",
|
||||
"emails.invitation.subject": "Undangan ke Tim %s di %s",
|
||||
"emails.invitation.hello": "Halo",
|
||||
"emails.invitation.body": "Email ini dikirimkan kepada Anda karena {{owner}} ingin mengundang Anda untuk menjadi anggota tim {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Jika Anda tidak tertarik, Anda dapat mengabaikan pesan ini.",
|
||||
"emails.invitation.thanks": "Terima kasih",
|
||||
"emails.invitation.signature": "Tim {{project}}",
|
||||
"locale.country.unknown": "Tidak diketahui",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "it",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Team %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verifica account",
|
||||
"emails.verification.hello": "Ciao {{name}}",
|
||||
"emails.verification.body": "Clicca questo link per verificare il tuo indirizzo email.",
|
||||
"emails.verification.footer": "Se non sei stato tu a richiedere la verifica dell’indirizzo email, puoi ignorare questo messaggio.",
|
||||
"emails.verification.thanks": "Grazie",
|
||||
"emails.verification.signature": "Il team {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Ciao,",
|
||||
"emails.magicSession.body": "Clicca questo link per accedere.",
|
||||
"emails.magicSession.footer": "Se non sei stato tu a richiedere di effettuare l’accesso, puoi ignorare questo messaggio.",
|
||||
"emails.magicSession.thanks": "Grazie",
|
||||
"emails.magicSession.signature": "Il team {{project}}",
|
||||
"emails.recovery.subject": "Reimpostazione password",
|
||||
"emails.recovery.hello": "Ciao {{name}}",
|
||||
"emails.recovery.body": "Clicca questo link per reimpostare la tua password di {{project}}.",
|
||||
"emails.recovery.footer": "Se non sei stato tu a richiedere la reimpostazione della password, puoi ignorare questo messaggio.",
|
||||
"emails.recovery.thanks": "Grazie",
|
||||
"emails.recovery.signature": "Il team {{project}}",
|
||||
"emails.invitation.subject": "Invito al Team %s per %s",
|
||||
"emails.invitation.hello": "Ciao",
|
||||
"emails.invitation.body": "Ricevi questa email perché {{owner}} ti ha invitato a diventare un membro del team {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Ignora questo messaggio se non sei interessato.",
|
||||
"emails.invitation.thanks": "Grazie",
|
||||
"emails.invitation.signature": "Il team {{project}}",
|
||||
"locale.country.unknown": "Sconosciuto",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ka",
|
||||
"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.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}} ನಿಮ್ಮನ್ನು {{team}} ತಂಡದ {{project}}ರಲ್ಲಿ ಸದಸ್ಯ ಆಗಲಿಕ್ಕೆ ಆಹ್ವಾನಿಸಿದ್ದಾರೆ",
|
||||
"emails.invitation.footer": "ನಿಮಗೆ ಆಸಕ್ತಿಯಿಲ್ಲದಿದ್ದರೆ, ಈ ಸಂದೇಶವನ್ನು ನಿರ್ಲಕ್ಷಿಸಿ",
|
||||
"emails.invitation.thanks": "ಧನ್ಯವಾದಗಳು",
|
||||
"emails.invitation.signature": "{{project}} ತಂಡ",
|
||||
"locale.country.unknown": "Unknown",
|
||||
"countries.af": "ಅಫ್ಘಾನಿಸ್ತಾನ",
|
||||
"countries.ao": "ಅಂಗೋಲಾ",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ko",
|
||||
"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.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": "앙골라",
|
||||
@@ -57,7 +63,7 @@
|
||||
"countries.cn": "중국",
|
||||
"countries.ci": "코트디부아르",
|
||||
"countries.cm": "카메룬",
|
||||
"countries.cd": "콩고공화국의 행정",
|
||||
"countries.cd": "콩고 민주 공화국",
|
||||
"countries.cg": "콩고 공화국",
|
||||
"countries.co": "콜롬비아",
|
||||
"countries.km": "코모로",
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.locale": "lb",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Kont Verifikatioun",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Follegt dëse Link fir Är E -Mail Adress z'iwwerpréiwen.",
|
||||
"emails.verification.footer": "Wann Dir net gefrot hutt dës Adress z'iwwerpréiwen, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.verification.thanks": "Merci",
|
||||
"emails.verification.signature": "{{project}} équipe",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Follegt dëse Link fir umellen.",
|
||||
"emails.magicSession.footer": "Wann Dir net gefrot hutt Iech mat dëser E -Mail anzemelden, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.magicSession.thanks": "Merci",
|
||||
"emails.magicSession.signature": "{{project}} équipe",
|
||||
"emails.recovery.subject": "Password Reset",
|
||||
"emails.recovery.hello": "Hello {{name}}",
|
||||
"emails.recovery.body": "Follegt dëse Link fir Äert {{project}} Passwuert zréckzesetzen.",
|
||||
"emails.recovery.footer": "Wann Dir net gefrot hutt Äert Passwuert zréckzesetzen, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.recovery.thanks": "Merci",
|
||||
"emails.recovery.signature": "{{project}} équipe",
|
||||
"emails.invitation.subject": "Invitatioun un %s équipe bei %s",
|
||||
"emails.invitation.hello": "Hallo",
|
||||
"emails.invitation.body": "Dës E -Mail gouf un Iech geschéckt well {{owner}} Iech invitéiere wëllt fir Member vum {{team}} Team bei {{project}} ze ginn.",
|
||||
"emails.invitation.footer": "Wann Dir net interesséiert sidd, kënnt Dir dëse Message ignoréieren.",
|
||||
"emails.invitation.thanks": "Merci",
|
||||
"emails.invitation.signature": "{{project}} équipe",
|
||||
"locale.country.unknown": "Onbekannt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albanien",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Vereenegt Arabesch Emirater",
|
||||
"countries.ar": "Argentinien",
|
||||
"countries.am": "Armenien",
|
||||
"countries.ag": "Antigua a Barbuda",
|
||||
"countries.au": "Australien",
|
||||
"countries.at": "Éisträich",
|
||||
"countries.az": "Aserbaidschan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belsch",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesch",
|
||||
"countries.bg": "Bulgarien",
|
||||
"countries.bh": "Bahrain",
|
||||
"countries.bs": "Bahamas",
|
||||
"countries.ba": "Bosnien an Herzegowina",
|
||||
"countries.by": "Wäissrussland",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolivien",
|
||||
"countries.br": "Brasilien",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Zentralafrikanesch Republik",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Schwäiz",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "China",
|
||||
"countries.ci": "Côte d'Ivoire",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republik Kongo",
|
||||
"countries.co": "Kolumbien",
|
||||
"countries.km": "Komoren",
|
||||
"countries.cv": "Cap Vert",
|
||||
"countries.cr": "Costa Rica",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Zypern",
|
||||
"countries.cz": "Tschechien",
|
||||
"countries.de": "Däitschland",
|
||||
"countries.dj": "Djibouti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Dänemark",
|
||||
"countries.do": "Dominikanesch Republik",
|
||||
"countries.dz": "Algerien",
|
||||
"countries.ec": "Ecuador",
|
||||
"countries.eg": "Ägypten",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Spuenien",
|
||||
"countries.ee": "Estland",
|
||||
"countries.et": "Äthiopien",
|
||||
"countries.fi": "Finnland",
|
||||
"countries.fj": "Fidschi",
|
||||
"countries.fr": "Frankräich",
|
||||
"countries.fm": "Mikronesien",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Vereenegt Kinnekräich",
|
||||
"countries.ge": "Georgien",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Äquatorialguinea",
|
||||
"countries.gr": "Griichenland",
|
||||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haïti",
|
||||
"countries.hu": "Ungarn",
|
||||
"countries.id": "Indonesien",
|
||||
"countries.in": "Indien",
|
||||
"countries.ie": "Irland",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Italien",
|
||||
"countries.jm": "Jamaika",
|
||||
"countries.jo": "Jordanien",
|
||||
"countries.jp": "Japan",
|
||||
"countries.kz": "Kazakhstan",
|
||||
"countries.ke": "Kenia",
|
||||
"countries.kg": "Kirgisistan",
|
||||
"countries.kh": "Kambodscha",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts and Nevis",
|
||||
"countries.kr": "Südkorea",
|
||||
"countries.kw": "Kuwait",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libyen",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litauen",
|
||||
"countries.lu": "Lëtzebuerg",
|
||||
"countries.lv": "Lettland",
|
||||
"countries.ma": "Marokko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Moldawien",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Malediven",
|
||||
"countries.mx": "Mexiko",
|
||||
"countries.mh": "Marshallinselen",
|
||||
"countries.mk": "Mazedonien",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Myanmar",
|
||||
"countries.me": "Montenegro",
|
||||
"countries.mn": "Mongolei",
|
||||
"countries.mz": "Mosambik",
|
||||
"countries.mr": "Mauritanien",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malaysien",
|
||||
"countries.na": "Namibien",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nicaragua",
|
||||
"countries.nl": "Holland",
|
||||
"countries.no": "Norwegen",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Neiséiland",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Philippinnen",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua-Neuguinea",
|
||||
"countries.pl": "Polen",
|
||||
"countries.kp": "Nordkorea",
|
||||
"countries.pt": "Portugal",
|
||||
"countries.py": "Paraguay",
|
||||
"countries.qa": "Quatar",
|
||||
"countries.ro": "Rumänien",
|
||||
"countries.ru": "Russland",
|
||||
"countries.rw": "Ruanda",
|
||||
"countries.sa": "Saudi Arabien",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Solomon Inselen",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "El Salvador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbien",
|
||||
"countries.ss": "Südsudan",
|
||||
"countries.st": "Sao Tome a Principe",
|
||||
"countries.sr": "Suriname",
|
||||
"countries.sk": "Slowakei",
|
||||
"countries.si": "Slowenien",
|
||||
"countries.se": "Schweden",
|
||||
"countries.sz": "Swasiland",
|
||||
"countries.sc": "Seychellen",
|
||||
"countries.sy": "Syrien",
|
||||
"countries.td": "Tschad",
|
||||
"countries.tg": "Goen",
|
||||
"countries.th": "Thailand",
|
||||
"countries.tj": "Tadjikistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor-Leste",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Tinidad an Tobago",
|
||||
"countries.tn": "Tunesien",
|
||||
"countries.tr": "Tierkei",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tansania",
|
||||
"countries.ug": "Ugana",
|
||||
"countries.ua": "Ukraine",
|
||||
"countries.uy": "Uruguay",
|
||||
"countries.us": "Vereenegt Staaten",
|
||||
"countries.uz": "Usbekistan",
|
||||
"countries.va": "Vatikan Stad",
|
||||
"countries.vc": "Saint Vincent an d'Grenadinnen",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Yemen",
|
||||
"countries.za": "Südafrika",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktis",
|
||||
"continents.as": "Asien",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Nordamerika",
|
||||
"continents.oc": "Ozeanien",
|
||||
"continents.sa": "Südamerika"
|
||||
}
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ml",
|
||||
"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.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": "Unknown",
|
||||
"countries.af": "അഫ്ഗാനിസ്ഥാൻ",
|
||||
"countries.ao": "അംഗോള",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ms",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Pengesahan Akaun",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Tekan pautan ini untuk mengesahkan alamat email anda.",
|
||||
"emails.verification.footer": "Sekiranya anda tidak membuat permintaan untuk mengesahkan email ini, sila abaikan mesej ini.",
|
||||
"emails.verification.thanks": "Terima kasih",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Log masuk",
|
||||
"emails.magicSession.hello": "Hey,",
|
||||
"emails.magicSession.body": "Tekan pautan ini untuk log masuk.",
|
||||
"emails.magicSession.footer": "Sekiranya anda tidak membuat permintaan untuk log masuk menggunakan email ini, sila abaikan mesej ini.",
|
||||
"emails.magicSession.thanks": "Terima kasih",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Menetap semula Kata Laluan",
|
||||
"emails.recovery.hello": "Hello {{name}}",
|
||||
"emails.recovery.body": "Tekan pautan ini untuk menetapkan semula kata laluan {{project}}.",
|
||||
"emails.recovery.footer": "Sekiranya anda tidak membuat permintaan menetap semula kata laluan, sila abaikan mesej ini.",
|
||||
"emails.recovery.thanks": "Terima kasih",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Jemputan ke pasukan %s di %s",
|
||||
"emails.invitation.hello": "Hello",
|
||||
"emails.invitation.body": "Anda menerima mel ini kerana {{owner}} ingin menjemput anda untuk menjadi ahli pasukan {{team}} di {{project}}.",
|
||||
"emails.invitation.footer": "Sekiranya anda tidak berminat, sila abaikan mesej ini.",
|
||||
"emails.invitation.thanks": "Terima kasih",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Tidak Diketahui",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
{
|
||||
"settings.inspire": "\"बुद्धिमान हुनु को कला के लाई बेवास्ता गर्न जान्ने को कला हो।\"",
|
||||
"settings.inspire": "\"के लाई बेवास्ता गर्ने भन्ने जान्नुनै बुद्धिमान हुनुको कला हो ।\"",
|
||||
"settings.locale": "ne",
|
||||
"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.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.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": "अंगोला",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "nl",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Account Verificatie",
|
||||
"emails.verification.hello": "Hoi {{name}}",
|
||||
"emails.verification.body": "Volg deze link om uw e-mail te verifieren",
|
||||
"emails.verification.footer": "Als u geen aanvraag voor verificatie heeft gemaakt, kan u deze mail negeren",
|
||||
"emails.verification.thanks": "Bedankt",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Hoi,",
|
||||
"emails.magicSession.body": "Volg deze link om in te loggen",
|
||||
"emails.magicSession.footer": "Als u geen aanvraag heeft gemaakt om met deze mail in te loggen, kan u deze mail negeren",
|
||||
"emails.magicSession.thanks": "Bedankt",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Wachtwoord Herinstellen",
|
||||
"emails.recovery.hello": "Hallo {{name}}",
|
||||
"emails.recovery.body": "Volg deze link om het wachtwoord van uw project {{project}} te wijzigen",
|
||||
"emails.recovery.footer": "Als u geen aanvraag heeft gemaakt om uw wachtwoord te wijzigen, kan u deze mail negeren",
|
||||
"emails.recovery.thanks": "Bedankt",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Uitnodiging van %s Team uit %s",
|
||||
"emails.invitation.hello": "Hallo,",
|
||||
"emails.invitation.body": "U ontvangt deze mail want u was uitgenodig door {{owner}} om lid van het {{team}} team te worden in {{project}} ",
|
||||
"emails.invitation.footer": "Als u niet geintereseerd bent, kan u deze mail negeren.",
|
||||
"emails.invitation.thanks": "Bedankt",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"locale.country.unknown": "Onbekend",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Noord Amerika",
|
||||
"continents.oc": "Oceanië",
|
||||
"continents.sa": "Zuid Amerika"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "no",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Kontobekreftelse",
|
||||
"emails.verification.hello": "Hallo {{name}}",
|
||||
"emails.verification.body": "Følg denne lenken for å bekrefte din e-post adresse.",
|
||||
"emails.verification.footer": "Dersom du ikke ba om å bekrefte e-post adressen, 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-post adressen, 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 sent 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",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Nord-Amerika",
|
||||
"continents.oc": "Oseania",
|
||||
"continents.sa": "Sør-Amerika"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
{
|
||||
"settings.inspire": "\"ଜ୍ଞାନୀ ହେବାର କଳା ହେଉଛି କ’ଣ ଅଣଦେଖା କରାଯିବ ଜାଣିବାର କଳା |\"",
|
||||
"settings.inspire": "\"ବୁଦ୍ଧିମାନ ହେବାର କଳା ହେଉଛି କ’ଣ ଅଣଦେଖା କରାଯିବ ଜାଣିବାର କଳା |\"",
|
||||
"settings.locale": "or",
|
||||
"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.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.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.af": "ଆଫଗାନିସ୍ତାନ",
|
||||
"countries.ao": "ଅଙ୍ଗୋଲା",
|
||||
"countries.al": "ଆଲବେନିଆ",
|
||||
"countries.ad": "ଆଣ୍ଡୋରା",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -1,226 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"Sztuka bycia mądrym to sztuka wiedzieć, co przeoczyć.\"",
|
||||
"settings.locale": "pl",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Zespół %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "",
|
||||
"locale.country.unknown": "Nieznany",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andora",
|
||||
"countries.ae": "Zjednoczone Emiraty Arabskie",
|
||||
"countries.ar": "Argentyna",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua i Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbejdżan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgia",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesz",
|
||||
"countries.bg": "Bułgaria",
|
||||
"countries.bh": "Bahrajn",
|
||||
"countries.bs": "Bahamy",
|
||||
"countries.ba": "Bośnia i Hercegowina",
|
||||
"countries.by": "Białoruś",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Boliwia",
|
||||
"countries.br": "Brazylia",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Republika Środkowoafrykańska",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Szwajcaria",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Chiny",
|
||||
"countries.ci": "Wybrzeże Kości Słoniowej",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republika Konga",
|
||||
"countries.co": "Kolumbia",
|
||||
"countries.km": "Komory",
|
||||
"countries.cv": "Republika Zielonego Przylądka",
|
||||
"countries.cr": "Kostaryka",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cypr",
|
||||
"countries.cz": "Czechy",
|
||||
"countries.de": "Niemcy",
|
||||
"countries.dj": "Dżibuti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Dania",
|
||||
"countries.do": "Republika Dominikańska",
|
||||
"countries.dz": "Algieria",
|
||||
"countries.ec": "Ekwador",
|
||||
"countries.eg": "Egipt",
|
||||
"countries.er": "Erytrea",
|
||||
"countries.es": "Hiszpania",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Etiopia",
|
||||
"countries.fi": "Finlandia",
|
||||
"countries.fj": "Fidżi",
|
||||
"countries.fr": "Francja",
|
||||
"countries.fm": "Mikronezja",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Wielka Brytania",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Gwinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Gwinea Bissau",
|
||||
"countries.gq": "Gwinea Równikowa",
|
||||
"countries.gr": "Grecja",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gwatemala",
|
||||
"countries.gy": "Gujana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorwacja",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Węgry",
|
||||
"countries.id": "Indonezja",
|
||||
"countries.in": "Indie",
|
||||
"countries.ie": "Irlandia",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Islandia",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Włochy",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japonia",
|
||||
"countries.kz": "Kazachstan",
|
||||
"countries.ke": "Kenia",
|
||||
"countries.kg": "Kirgistan",
|
||||
"countries.kh": "Kambodża",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts i Nevis",
|
||||
"countries.kr": "Korea Południowa",
|
||||
"countries.kw": "Kuwejt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Liban",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litwa",
|
||||
"countries.lu": "Luksemburg",
|
||||
"countries.lv": "Łotwa",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Mołdawia",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Malediwy",
|
||||
"countries.mx": "Meksyk",
|
||||
"countries.mh": "Wyspy Marshalla",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Birma",
|
||||
"countries.me": "Czarnogóra",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauretania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malezja",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nikaragua",
|
||||
"countries.nl": "Holandia",
|
||||
"countries.no": "Norwegia",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Nowa Zelandia",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipiny",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Nowa Gwinea",
|
||||
"countries.pl": "Polska",
|
||||
"countries.kp": "Korea Północna",
|
||||
"countries.pt": "Portugalia",
|
||||
"countries.py": "Paragwaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunia",
|
||||
"countries.ru": "Rosja",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Arabia Saudyjska",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Wyspy Salomona",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "Salwador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "Sudan Południowy",
|
||||
"countries.st": "Wyspy Świętego Tomasza i Książęca",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Słowacja",
|
||||
"countries.si": "Słowenia",
|
||||
"countries.se": "Szwecja",
|
||||
"countries.sz": "Suazi",
|
||||
"countries.sc": "Seszele",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Czad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Tajlandia",
|
||||
"countries.tj": "Tadżykistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor Wschodni",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trynidad i Tobago",
|
||||
"countries.tn": "Tunezja",
|
||||
"countries.tr": "Turcja",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraina",
|
||||
"countries.uy": "Urugwaj",
|
||||
"countries.us": "Stany Zjednoczone",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Watykan",
|
||||
"countries.vc": "Saint Vincent i Grenadyny",
|
||||
"countries.ve": "Wenezuela",
|
||||
"countries.vn": "Wietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Republika Południowej Afryki",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afryka",
|
||||
"continents.an": "Antarktyda",
|
||||
"continents.as": "Azja",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Ameryka Północna",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "Ameryka południowa"
|
||||
}
|
||||
"settings.inspire": "\"Sztuka bycia mądrym to sztuka wiedzieć, co przeoczyć.\"",
|
||||
"settings.locale": "pl",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Zespół %s",
|
||||
"emails.verification.subject": "Weryfikacja konta",
|
||||
"emails.verification.hello": "Cześć {{name}}",
|
||||
"emails.verification.body": "Przejdź do tego linku, aby zweryfikować swój adres e-mail.",
|
||||
"emails.verification.footer": "Jeśli to nie Ty prosiłeś o zweryfikowanie tego adresu, możesz zignorować tę wiadomość.",
|
||||
"emails.verification.thanks": "Dziękujemy",
|
||||
"emails.verification.signature": "Zespół {{project}}",
|
||||
"emails.magicSession.subject": "Logowanie",
|
||||
"emails.magicSession.hello": "Cześć,",
|
||||
"emails.magicSession.body": "Przejdź do tego linku, aby zalogować się.",
|
||||
"emails.magicSession.footer": "Jeśli to nie Ty prosiłeś o logowanie przy użyciu tego adresu e-mail, możesz zignorować tę wiadomość.",
|
||||
"emails.magicSession.thanks": "Dziękujemy",
|
||||
"emails.magicSession.signature": "Zespół {{project}}",
|
||||
"emails.recovery.subject": "Resetowanie hasła",
|
||||
"emails.recovery.hello": "Cześć {{name}}",
|
||||
"emails.recovery.body": "Przejdź do tego linku, aby zresetować hasło dla {{project}}.",
|
||||
"emails.recovery.footer": "Jeśli to nie Ty prosiłeś o zresetowanie swojego hasła, możesz zignorować tę wiadomość.",
|
||||
"emails.recovery.thanks": "Dziękujemy",
|
||||
"emails.recovery.signature": "Zespół {{project}}",
|
||||
"emails.invitation.subject": "Zaproszenie do zespołu %s w %s",
|
||||
"emails.invitation.hello": "Cześć",
|
||||
"emails.invitation.body": "Otrzymujesz tę wiadomość, ponieważ {{owner}} zaprasza Cię do grona członków zespołu {{team}} w projekcie {{project}}.",
|
||||
"emails.invitation.footer": "Jeśli nie jesteś zainteresowany, możesz zignorować tę wiadomość.",
|
||||
"emails.invitation.thanks": "Dziękujemy",
|
||||
"emails.invitation.signature": "Zespół {{project}}",
|
||||
"locale.country.unknown": "Nieznany",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albania",
|
||||
"countries.ad": "Andora",
|
||||
"countries.ae": "Zjednoczone Emiraty Arabskie",
|
||||
"countries.ar": "Argentyna",
|
||||
"countries.am": "Armenia",
|
||||
"countries.ag": "Antigua i Barbuda",
|
||||
"countries.au": "Australia",
|
||||
"countries.at": "Austria",
|
||||
"countries.az": "Azerbejdżan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgia",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladesz",
|
||||
"countries.bg": "Bułgaria",
|
||||
"countries.bh": "Bahrajn",
|
||||
"countries.bs": "Bahamy",
|
||||
"countries.ba": "Bośnia i Hercegowina",
|
||||
"countries.by": "Białoruś",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Boliwia",
|
||||
"countries.br": "Brazylia",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunei",
|
||||
"countries.bt": "Bhutan",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Republika Środkowoafrykańska",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Szwajcaria",
|
||||
"countries.cl": "Chile",
|
||||
"countries.cn": "Chiny",
|
||||
"countries.ci": "Wybrzeże Kości Słoniowej",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "DR Congo",
|
||||
"countries.cg": "Republika Konga",
|
||||
"countries.co": "Kolumbia",
|
||||
"countries.km": "Komory",
|
||||
"countries.cv": "Republika Zielonego Przylądka",
|
||||
"countries.cr": "Kostaryka",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cypr",
|
||||
"countries.cz": "Czechy",
|
||||
"countries.de": "Niemcy",
|
||||
"countries.dj": "Dżibuti",
|
||||
"countries.dm": "Dominica",
|
||||
"countries.dk": "Dania",
|
||||
"countries.do": "Republika Dominikańska",
|
||||
"countries.dz": "Algieria",
|
||||
"countries.ec": "Ekwador",
|
||||
"countries.eg": "Egipt",
|
||||
"countries.er": "Erytrea",
|
||||
"countries.es": "Hiszpania",
|
||||
"countries.ee": "Estonia",
|
||||
"countries.et": "Etiopia",
|
||||
"countries.fi": "Finlandia",
|
||||
"countries.fj": "Fidżi",
|
||||
"countries.fr": "Francja",
|
||||
"countries.fm": "Mikronezja",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Wielka Brytania",
|
||||
"countries.ge": "Georgia",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Gwinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Gwinea Bissau",
|
||||
"countries.gq": "Gwinea Równikowa",
|
||||
"countries.gr": "Grecja",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gwatemala",
|
||||
"countries.gy": "Gujana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorwacja",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Węgry",
|
||||
"countries.id": "Indonezja",
|
||||
"countries.in": "Indie",
|
||||
"countries.ie": "Irlandia",
|
||||
"countries.ir": "Iran",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Islandia",
|
||||
"countries.il": "Israel",
|
||||
"countries.it": "Włochy",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordan",
|
||||
"countries.jp": "Japonia",
|
||||
"countries.kz": "Kazachstan",
|
||||
"countries.ke": "Kenia",
|
||||
"countries.kg": "Kirgistan",
|
||||
"countries.kh": "Kambodża",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Saint Kitts i Nevis",
|
||||
"countries.kr": "Korea Południowa",
|
||||
"countries.kw": "Kuwejt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Liban",
|
||||
"countries.lr": "Liberia",
|
||||
"countries.ly": "Libia",
|
||||
"countries.lc": "Saint Lucia",
|
||||
"countries.li": "Liechtenstein",
|
||||
"countries.lk": "Sri Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litwa",
|
||||
"countries.lu": "Luksemburg",
|
||||
"countries.lv": "Łotwa",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monaco",
|
||||
"countries.md": "Mołdawia",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Malediwy",
|
||||
"countries.mx": "Meksyk",
|
||||
"countries.mh": "Wyspy Marshalla",
|
||||
"countries.mk": "Macedonia",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Birma",
|
||||
"countries.me": "Czarnogóra",
|
||||
"countries.mn": "Mongolia",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauretania",
|
||||
"countries.mu": "Mauritius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malezja",
|
||||
"countries.na": "Namibia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigeria",
|
||||
"countries.ni": "Nikaragua",
|
||||
"countries.nl": "Holandia",
|
||||
"countries.no": "Norwegia",
|
||||
"countries.np": "Nepal",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Nowa Zelandia",
|
||||
"countries.om": "Oman",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipiny",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua Nowa Gwinea",
|
||||
"countries.pl": "Polska",
|
||||
"countries.kp": "Korea Północna",
|
||||
"countries.pt": "Portugalia",
|
||||
"countries.py": "Paragwaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunia",
|
||||
"countries.ru": "Rosja",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Arabia Saudyjska",
|
||||
"countries.sd": "Sudan",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Wyspy Salomona",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "Salwador",
|
||||
"countries.sm": "San Marino",
|
||||
"countries.so": "Somalia",
|
||||
"countries.rs": "Serbia",
|
||||
"countries.ss": "Sudan Południowy",
|
||||
"countries.st": "Wyspy Świętego Tomasza i Książęca",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Słowacja",
|
||||
"countries.si": "Słowenia",
|
||||
"countries.se": "Szwecja",
|
||||
"countries.sz": "Suazi",
|
||||
"countries.sc": "Seszele",
|
||||
"countries.sy": "Syria",
|
||||
"countries.td": "Czad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Tajlandia",
|
||||
"countries.tj": "Tadżykistan",
|
||||
"countries.tm": "Turkmenistan",
|
||||
"countries.tl": "Timor Wschodni",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trynidad i Tobago",
|
||||
"countries.tn": "Tunezja",
|
||||
"countries.tr": "Turcja",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzania",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukraina",
|
||||
"countries.uy": "Urugwaj",
|
||||
"countries.us": "Stany Zjednoczone",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Watykan",
|
||||
"countries.vc": "Saint Vincent i Grenadyny",
|
||||
"countries.ve": "Wenezuela",
|
||||
"countries.vn": "Wietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Republika Południowej Afryki",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afryka",
|
||||
"continents.an": "Antarktyda",
|
||||
"continents.as": "Azja",
|
||||
"continents.eu": "Europa",
|
||||
"continents.na": "Ameryka Północna",
|
||||
"continents.oc": "Oceania",
|
||||
"continents.sa": "Ameryka południowa"
|
||||
}
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "pt-br",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Time %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verificação da Conta",
|
||||
"emails.verification.hello": "Olá {{name}}",
|
||||
"emails.verification.body": "Clique neste link para verificar o seu endereço de e-mail.",
|
||||
"emails.verification.footer": "Se não você que solicitou essa verificação deste e-mail, você pode ignorar essa mensagem",
|
||||
"emails.verification.thanks": "Muito obrigado",
|
||||
"emails.verification.signature": "Time {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Olá,",
|
||||
"emails.magicSession.body": "Clique neste link para entrar",
|
||||
"emails.magicSession.footer": "Se não você que solicitou essa verificação deste e-mail, você pode ignorar essa mensagem",
|
||||
"emails.magicSession.thanks": "Muito obrigado",
|
||||
"emails.magicSession.signature": "Time {{project}}",
|
||||
"emails.recovery.subject": "Redefinação de senha",
|
||||
"emails.recovery.hello": "Olá {{name}}",
|
||||
"emails.recovery.body": "Clique neste link para redefinir sua senha do {{project}}.",
|
||||
"emails.recovery.footer": "Se você não solicitou a redefinição da sua senha, você pode ignorar essa mensagem",
|
||||
"emails.recovery.thanks": "Muito obrigado",
|
||||
"emails.recovery.signature": "Time {{project}}",
|
||||
"emails.invitation.subject": "Convite para o Time %s em %s",
|
||||
"emails.invitation.hello": "Olá",
|
||||
"emails.invitation.body": "Este email foi enviado porque o {{owner}} deseja convidar você a se tornar membro do Time {{team}} em {{project}}.",
|
||||
"emails.invitation.footer": "Se você não está interessado, você pode ignorar essa mensagem",
|
||||
"emails.invitation.thanks": "Muito obrigado",
|
||||
"emails.invitation.signature": "Time {{project}}",
|
||||
"locale.country.unknown": "Desconhecido",
|
||||
"countries.af": "Afeganistão",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "pt-pt",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "Equipa %s",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verificação de contas",
|
||||
"emails.verification.hello": "Hey {{name}}",
|
||||
"emails.verification.body": "Siga esta ligação para verificar o seu endereço de correio electrónico.",
|
||||
"emails.verification.footer": "Se não pediu para verificar este endereço, pode ignorar esta mensagem.",
|
||||
"emails.verification.thanks": "Obrigado",
|
||||
"emails.verification.signature": "Equipa {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Olá ,",
|
||||
"emails.magicSession.body": "Siga esta ligação para iniciar sessão.",
|
||||
"emails.magicSession.footer": "Se não pediu para entrar usando este e-mail, pode ignorar esta mensagem.",
|
||||
"emails.magicSession.thanks": "Obrigado",
|
||||
"emails.magicSession.signature": "Equipa {{project}}",
|
||||
"emails.recovery.subject": "Redefinição de senha",
|
||||
"emails.recovery.hello": "Olá {{name}}",
|
||||
"emails.recovery.body": "tilize este link para redefinir a palavra-passe do seu projecto {{project}}",
|
||||
"emails.recovery.footer": "Se não pediu para redefinir a sua palavra-passe, pode ignorar esta mensagem.",
|
||||
"emails.recovery.thanks": "Obrigado",
|
||||
"emails.recovery.signature": "Equipa {{project}}",
|
||||
"emails.invitation.subject": "Convite à equipa de %s às %s",
|
||||
"emails.invitation.hello": "Olá",
|
||||
"emails.invitation.body": "Este correio foi-lhe enviado porque {{owner}} queria convidá-lo a tornar-se membro da equipa {{team}} da {{project}}.",
|
||||
"emails.invitation.footer": "Se não estiver interessado, pode ignorar esta mensagem.",
|
||||
"emails.invitation.thanks": "Obrigado",
|
||||
"emails.invitation.signature": "Equipa {{project}}",
|
||||
"locale.country.unknown": "Desconhecido",
|
||||
"countries.af": "Afeganistão",
|
||||
"countries.ao": "Angola",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "América do Norte",
|
||||
"continents.oc": "Oceânia",
|
||||
"continents.sa": "América do Sul"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ro",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Echipa",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verificare cont",
|
||||
"emails.verification.hello": "Bună ziua, {{name}}",
|
||||
"emails.verification.body": "Click pe acest link pentru a valida adresa de email.",
|
||||
"emails.verification.footer": "Dacă nu ai cerut validarea adresei de email, poți ignora acest mesaj.",
|
||||
"emails.verification.thanks": "Mulțumim",
|
||||
"emails.verification.signature": "Echipa {{project}}",
|
||||
"emails.magicSession.subject": "Login",
|
||||
"emails.magicSession.hello": "Bună ziua,",
|
||||
"emails.magicSession.body": "Urmează acest link pentru logare.",
|
||||
"emails.magicSession.footer": "Dacă nu ai incercat să te loghezi folosing această adresa de email, poți ignora acest mesaj.",
|
||||
"emails.magicSession.thanks": "Mulțumim",
|
||||
"emails.magicSession.signature": "Echipa {{project}}",
|
||||
"emails.recovery.subject": "Resetare parolă",
|
||||
"emails.recovery.hello": "Bună ziua, {{name}}",
|
||||
"emails.recovery.body": "Click aici pentru a reseta parola pentru {{project}}",
|
||||
"emails.recovery.footer": "Dacă nu ai cerut să îți schimbi parola, ignoră acest mesaj.",
|
||||
"emails.recovery.thanks": "Mulțumim",
|
||||
"emails.recovery.signature": "Echipa {{project}}",
|
||||
"emails.invitation.subject": "Invitatie catre %s Echipa la %s",
|
||||
"emails.invitation.hello": "Bună ziua",
|
||||
"emails.invitation.body": "Acest email a fost trimis pentru că {{owner}} a vrut ca tu să devii membru al echipei {{team}} la {{project}}.",
|
||||
"emails.invitation.footer": "Dacă nu esti interesat, poți ignora acest email.",
|
||||
"emails.invitation.thanks": "Mulțumim",
|
||||
"emails.invitation.signature": "Echipa {{project}}",
|
||||
"locale.country.unknown": "Necunoscut",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "ru",
|
||||
"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.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}} приглашает стать членом команды {{team}} в проекте {{project}}.",
|
||||
"emails.invitation.footer": "Если вы не заинтересованы, проигнорируйте это сообщение.",
|
||||
"emails.invitation.thanks": "Спасибо",
|
||||
"emails.invitation.signature": "команда {{project}}",
|
||||
"locale.country.unknown": "Неизвестно",
|
||||
"countries.af": "Афганистан",
|
||||
"countries.ao": "Ангола",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Северная Америка",
|
||||
"continents.oc": "Океания",
|
||||
"continents.sa": "Южная Америка"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"किं हेयमित्यस्य ज्ञानमेव ज्ञानिलक्षणम्।\"",
|
||||
"settings.locale": "sa",
|
||||
"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}} {{team}} गणे {{project}} मध्ये भवद्योगदानमच्छितीति हेतोः पत्रमदिं भवत्सकाशं प्रेषतिम्।",
|
||||
"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": "कांगो लोकतांत्रिक गणराज्यम्",
|
||||
"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": "दक्षिण अमेरिका"
|
||||
}
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"settings.inspire": "\"Umenie múdrosti je umenie vedieť, čo prehliadnuť.\"",
|
||||
"settings.locale": "sk",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Tím",
|
||||
"emails.verification.subject": "Overenie účtu",
|
||||
"emails.verification.hello": "Ahoj {{name}}",
|
||||
"emails.verification.body": "Použi tento link pre overenie svojej emailovej adresy.",
|
||||
"emails.verification.footer": "Ak si nepožiadal o overenie tejto adresy, môžeš túto správu ignorovať.",
|
||||
"emails.verification.thanks": "Ďakujeme.",
|
||||
"emails.verification.signature": "{{project}} tím",
|
||||
"emails.magicSession.subject": "Prihlásenie",
|
||||
"emails.magicSession.hello": "Ahoj,",
|
||||
"emails.magicSession.body": "Použi tento link pre prihlásenie.",
|
||||
"emails.magicSession.footer": "Ak si nepožiadal o prihlásenie cez email, túto správu môžeš ignorovať.",
|
||||
"emails.magicSession.thanks": "Ďakujeme",
|
||||
"emails.magicSession.signature": "{{project}} tím",
|
||||
"emails.recovery.subject": "Obnovenie hesla",
|
||||
"emails.recovery.hello": "Ahoj {{name}}",
|
||||
"emails.recovery.body": "Použi tento link pre obnovenie svojho {{project}} hesla.",
|
||||
"emails.recovery.footer": "Ak si nepožiadal o obnovu svojho hesla, túto správu môžeš ignorovať.",
|
||||
"emails.recovery.thanks": "Ďakujeme",
|
||||
"emails.recovery.signature": "{{project}} tím",
|
||||
"emails.invitation.subject": "Pozvánka do %s Tímu v %s",
|
||||
"emails.invitation.hello": "Ahoj",
|
||||
"emails.invitation.body": "Tento email ti bol zaslaný, pretože {{owner}} ťa pozval, aby si sa stal členom {{team}} tímu v projekte {{project}}.",
|
||||
"emails.invitation.footer": "Ak nemáš záujem, môžeš túto správu ignorovať.",
|
||||
"emails.invitation.thanks": "Ďakujeme",
|
||||
"emails.invitation.signature": "{{project}} tím",
|
||||
"locale.country.unknown": "Neznámy",
|
||||
"countries.af": "Afganistan",
|
||||
"countries.ao": "Angola",
|
||||
"countries.al": "Albánsko",
|
||||
"countries.ad": "Andorra",
|
||||
"countries.ae": "Spojené arabské emiráty",
|
||||
"countries.ar": "Argentína",
|
||||
"countries.am": "Arménsko",
|
||||
"countries.ag": "Antigua a Barbuda",
|
||||
"countries.au": "Austrália",
|
||||
"countries.at": "Rakúsko",
|
||||
"countries.az": "Azerbajdžan",
|
||||
"countries.bi": "Burundi",
|
||||
"countries.be": "Belgicko",
|
||||
"countries.bj": "Benin",
|
||||
"countries.bf": "Burkina Faso",
|
||||
"countries.bd": "Bangladéš",
|
||||
"countries.bg": "Bulharsko",
|
||||
"countries.bh": "Bahrajn",
|
||||
"countries.bs": "Bahamy",
|
||||
"countries.ba": "Bosnia and Herzegovina",
|
||||
"countries.by": "Bielorusko",
|
||||
"countries.bz": "Belize",
|
||||
"countries.bo": "Bolívia",
|
||||
"countries.br": "Brazília",
|
||||
"countries.bb": "Barbados",
|
||||
"countries.bn": "Brunej",
|
||||
"countries.bt": "Bhután",
|
||||
"countries.bw": "Botswana",
|
||||
"countries.cf": "Stredoafrická republika",
|
||||
"countries.ca": "Kanada",
|
||||
"countries.ch": "Švajčiarsko",
|
||||
"countries.cl": "Čile",
|
||||
"countries.cn": "Čína",
|
||||
"countries.ci": "Pobrežie Slonoviny",
|
||||
"countries.cm": "Kamerun",
|
||||
"countries.cd": "Konžská demokratická republika",
|
||||
"countries.cg": "Kongo",
|
||||
"countries.co": "Kolumbia",
|
||||
"countries.km": "Komory",
|
||||
"countries.cv": "Kapverdy",
|
||||
"countries.cr": "Kostarika",
|
||||
"countries.cu": "Kuba",
|
||||
"countries.cy": "Cyprus",
|
||||
"countries.cz": "Česko",
|
||||
"countries.de": "Nemecko",
|
||||
"countries.dj": "Džibutsko",
|
||||
"countries.dm": "Dominika",
|
||||
"countries.dk": "Denmark",
|
||||
"countries.do": "Dominikánska republika",
|
||||
"countries.dz": "Alžírsko",
|
||||
"countries.ec": "Ekvádor",
|
||||
"countries.eg": "Egypt",
|
||||
"countries.er": "Eritrea",
|
||||
"countries.es": "Španielsko",
|
||||
"countries.ee": "Estónsko",
|
||||
"countries.et": "Etiópia",
|
||||
"countries.fi": "Fínsko",
|
||||
"countries.fj": "Fidži",
|
||||
"countries.fr": "Francúzsko",
|
||||
"countries.fm": "Mikronézia",
|
||||
"countries.ga": "Gabon",
|
||||
"countries.gb": "Spojené kráľovstvo",
|
||||
"countries.ge": "Gruzínsko",
|
||||
"countries.gh": "Ghana",
|
||||
"countries.gn": "Guinea",
|
||||
"countries.gm": "Gambia",
|
||||
"countries.gw": "Guinea-Bissau",
|
||||
"countries.gq": "Rovníková Guinea",
|
||||
"countries.gr": "Grécko",
|
||||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorvátsko",
|
||||
"countries.ht": "Haiti",
|
||||
"countries.hu": "Maďarsko",
|
||||
"countries.id": "Indonézia",
|
||||
"countries.in": "India",
|
||||
"countries.ie": "Írsko",
|
||||
"countries.ir": "Irán",
|
||||
"countries.iq": "Irak",
|
||||
"countries.is": "Island",
|
||||
"countries.il": "Izrael",
|
||||
"countries.it": "Taliansko",
|
||||
"countries.jm": "Jamajka",
|
||||
"countries.jo": "Jordánsko",
|
||||
"countries.jp": "Japonsko",
|
||||
"countries.kz": "Kazachstan",
|
||||
"countries.ke": "Keňa",
|
||||
"countries.kg": "Kirgizsko",
|
||||
"countries.kh": "Kambodža",
|
||||
"countries.ki": "Kiribati",
|
||||
"countries.kn": "Svätý Krištof a Nevis",
|
||||
"countries.kr": "Južná Kórea",
|
||||
"countries.kw": "Kuvajt",
|
||||
"countries.la": "Laos",
|
||||
"countries.lb": "Libanon",
|
||||
"countries.lr": "Libéria",
|
||||
"countries.ly": "Líbya",
|
||||
"countries.lc": "Svätá Lucia",
|
||||
"countries.li": "Lichtenštajnsko",
|
||||
"countries.lk": "Srí Lanka",
|
||||
"countries.ls": "Lesotho",
|
||||
"countries.lt": "Litva",
|
||||
"countries.lu": "Luxembursko",
|
||||
"countries.lv": "Lotyšsko",
|
||||
"countries.ma": "Maroko",
|
||||
"countries.mc": "Monako",
|
||||
"countries.md": "Moldavsko",
|
||||
"countries.mg": "Madagaskar",
|
||||
"countries.mv": "Maldivy",
|
||||
"countries.mx": "Mexiko",
|
||||
"countries.mh": "Marshall Islands",
|
||||
"countries.mk": "Macedónsko",
|
||||
"countries.ml": "Mali",
|
||||
"countries.mt": "Malta",
|
||||
"countries.mm": "Mjanmarsko",
|
||||
"countries.me": "Čierna Hora",
|
||||
"countries.mn": "Monglosko",
|
||||
"countries.mz": "Mozambik",
|
||||
"countries.mr": "Mauritánia",
|
||||
"countries.mu": "Maurícius",
|
||||
"countries.mw": "Malawi",
|
||||
"countries.my": "Malajzia",
|
||||
"countries.na": "Namíbia",
|
||||
"countries.ne": "Niger",
|
||||
"countries.ng": "Nigéria",
|
||||
"countries.ni": "Nikaragua",
|
||||
"countries.nl": "Holandsko",
|
||||
"countries.no": "Nórsko",
|
||||
"countries.np": "Nepál",
|
||||
"countries.nr": "Nauru",
|
||||
"countries.nz": "Nový Zéland",
|
||||
"countries.om": "Omán",
|
||||
"countries.pk": "Pakistan",
|
||||
"countries.pa": "Panama",
|
||||
"countries.pe": "Peru",
|
||||
"countries.ph": "Filipíny",
|
||||
"countries.pw": "Palau",
|
||||
"countries.pg": "Papua-Nová Guinea",
|
||||
"countries.pl": "Poľsko",
|
||||
"countries.kp": "Severná Kórea",
|
||||
"countries.pt": "Portugalsko",
|
||||
"countries.py": "Paraguaj",
|
||||
"countries.qa": "Katar",
|
||||
"countries.ro": "Rumunsko",
|
||||
"countries.ru": "Rusko",
|
||||
"countries.rw": "Rwanda",
|
||||
"countries.sa": "Saudská Arábia",
|
||||
"countries.sd": "Sudán",
|
||||
"countries.sn": "Senegal",
|
||||
"countries.sg": "Singapur",
|
||||
"countries.sb": "Šalamúnove ostrovy",
|
||||
"countries.sl": "Sierra Leone",
|
||||
"countries.sv": "Salvádor",
|
||||
"countries.sm": "San Maríno",
|
||||
"countries.so": "Somálsko",
|
||||
"countries.rs": "Srbsko",
|
||||
"countries.ss": "Južný Sudán",
|
||||
"countries.st": "Svätý Tomáš a Princov ostrov",
|
||||
"countries.sr": "Surinam",
|
||||
"countries.sk": "Slovensko",
|
||||
"countries.si": "Slovinsko",
|
||||
"countries.se": "Švédsko",
|
||||
"countries.sz": "Svazijsko",
|
||||
"countries.sc": "Seychely",
|
||||
"countries.sy": "Sýria",
|
||||
"countries.td": "Čad",
|
||||
"countries.tg": "Togo",
|
||||
"countries.th": "Thajsko",
|
||||
"countries.tj": "Tadžikistan",
|
||||
"countries.tm": "Turkménsko",
|
||||
"countries.tl": "Východný Timor",
|
||||
"countries.to": "Tonga",
|
||||
"countries.tt": "Trinidad a Tobago",
|
||||
"countries.tn": "Tunisko",
|
||||
"countries.tr": "Turecko",
|
||||
"countries.tv": "Tuvalu",
|
||||
"countries.tz": "Tanzánia",
|
||||
"countries.ug": "Uganda",
|
||||
"countries.ua": "Ukrajna",
|
||||
"countries.uy": "Uruguaj",
|
||||
"countries.us": "Spojené štáty",
|
||||
"countries.uz": "Uzbekistan",
|
||||
"countries.va": "Vatikán",
|
||||
"countries.vc": "Svätý Vincent a Grenadíny",
|
||||
"countries.ve": "Venezuela",
|
||||
"countries.vn": "Vietnam",
|
||||
"countries.vu": "Vanuatu",
|
||||
"countries.ws": "Samoa",
|
||||
"countries.ye": "Jemen",
|
||||
"countries.za": "Južná Afrika",
|
||||
"countries.zm": "Zambia",
|
||||
"countries.zw": "Zimbabwe",
|
||||
"continents.af": "Afrika",
|
||||
"continents.an": "Antarktída",
|
||||
"continents.as": "Ázia",
|
||||
"continents.eu": "Európa",
|
||||
"continents.na": "Severná Amerika",
|
||||
"continents.oc": "Oceánia",
|
||||
"continents.sa": "Južná Amerika"
|
||||
}
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "sv",
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s-teamet",
|
||||
"emails.verification.subject": "",
|
||||
"emails.verification.hello": "",
|
||||
"emails.verification.body": "",
|
||||
"emails.verification.footer": "",
|
||||
"emails.verification.thanks": "",
|
||||
"emails.verification.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": "Verifiera konto",
|
||||
"emails.verification.hello": "Hej {{name}}",
|
||||
"emails.verification.body": "Klicka på denna länk för att verifiera din email",
|
||||
"emails.verification.footer": "Om du inte bad om att verifiera den här e-postadressen kan du ignorera detta mail.",
|
||||
"emails.verification.thanks": "Tack",
|
||||
"emails.verification.signature": "{{project}} teamet",
|
||||
"emails.magicSession.subject": "Logga in",
|
||||
"emails.magicSession.hello": "Hej,",
|
||||
"emails.magicSession.body": "Klicka på denna länk för att logga in.",
|
||||
"emails.magicSession.footer": "Om du inte bad om att logga in med denna e-postadress kan du ignorera detta mail.",
|
||||
"emails.magicSession.thanks": "Tack",
|
||||
"emails.magicSession.signature": "{{project}} teamet",
|
||||
"emails.recovery.subject": "Återställ lösenord",
|
||||
"emails.recovery.hello": "Hej {{name}}",
|
||||
"emails.recovery.body": "Klicka på denna länk för att återställa lösenordet på {{project}}",
|
||||
"emails.recovery.footer": "Om du inte bad om att återställa ditt lösenord kan du ignorera detta mail.",
|
||||
"emails.recovery.thanks": "Tack",
|
||||
"emails.recovery.signature": "{{project}} teamet",
|
||||
"emails.invitation.subject": "Inbjudan till %s teamet på %s",
|
||||
"emails.invitation.hello": "Hej",
|
||||
"emails.invitation.body": "Detta mail skickades till dig eftersom {{owner}} ville bjuda in dig att bli medlem i teamet {{team}} på {{project}}.",
|
||||
"emails.invitation.footer": "Om du inte är intresserad kan du ignorera detta mail.",
|
||||
"emails.invitation.thanks": "Tack",
|
||||
"emails.invitation.signature": "{{project}} teamet",
|
||||
"locale.country.unknown": "Okänt",
|
||||
"countries.af": "Afghanistan",
|
||||
"countries.ao": "Angola",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
{
|
||||
"settings.inspire": "\"ศิลปะแห่งความฉลาดคือศิลปะแห่งการรู้ว่าจะมองข้ามอะไร\"",
|
||||
"settings.inspire": "\"ศิลปะของการมีปัญญา คือการตระหนักได้ว่าควรจะมองข้ามเรื่องอะไร\"",
|
||||
"settings.locale": "th",
|
||||
"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.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.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}} ต้องการที่จะเชิญชวนคุณเข้าร่วมเป็นส่วนหนึ่งของ ทีม {{team}} จากโปรเจกต์ {{project}}",
|
||||
"emails.invitation.footer": "หากท่านไม่ได้สนใจที่จะเข้าร่วม ท่านสามารถเพิกเฉยข้อความนี้ได้",
|
||||
"emails.invitation.thanks": "ขอบคุณ",
|
||||
"emails.invitation.signature": "ทีม {{project}}",
|
||||
"locale.country.unknown": "ไม่ทราบ",
|
||||
"countries.af": "อัฟกานิสถาน",
|
||||
"countries.ao": "แองโกลา",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
{
|
||||
"settings.inspire": "\"The art of being wise is the art of knowing what to overlook.\"",
|
||||
"settings.inspire": "\"Мистецтво бути мудрим - це мистецтво знати, чим можна знехтувати\"",
|
||||
"settings.locale": "uk",
|
||||
"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.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}} запрошує вас стати членом команди {{team}} у проекті {{project}}.",
|
||||
"emails.invitation.footer": "Якщо ви не зацікавлені, проігноруйте це повідомлення.",
|
||||
"emails.invitation.thanks": "Дякуємо",
|
||||
"emails.invitation.signature": "команда {{project}}",
|
||||
"locale.country.unknown": "Невідомо",
|
||||
"countries.af": "Афганістан",
|
||||
"countries.ao": "Ангола",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "Північна Америка",
|
||||
"continents.oc": "Океанія",
|
||||
"continents.sa": "Південна Америка"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -3,24 +3,30 @@
|
||||
"settings.locale": "zh",
|
||||
"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.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}} 想邀请您成为 {{team}} 团队在 {{project}}.",
|
||||
"emails.invitation.footer": "如果您不感兴趣,可以忽略此消息。",
|
||||
"emails.invitation.thanks": "谢谢",
|
||||
"emails.invitation.signature": "{{project}} 团队",
|
||||
"locale.country.unknown": "未知",
|
||||
"countries.af": "阿富汗",
|
||||
"countries.ao": "安哥拉",
|
||||
@@ -223,4 +229,4 @@
|
||||
"continents.na": "北美洲",
|
||||
"continents.oc": "大洋洲",
|
||||
"continents.sa": "南美洲"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"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": "",
|
||||
|
||||
@@ -15,7 +15,7 @@ return [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '4.0.1',
|
||||
'version' => '4.0.3',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -62,11 +62,11 @@ return [
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '1.0.2',
|
||||
'version' => '2.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'beta' => false,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
@@ -152,7 +152,7 @@ return [
|
||||
'name' => 'Console',
|
||||
'enabled' => false,
|
||||
'beta' => false,
|
||||
'languages' => [ // TODO change key to 'sdks'
|
||||
'languages' => [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Console',
|
||||
@@ -179,7 +179,7 @@ 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',
|
||||
@@ -217,7 +217,7 @@ return [
|
||||
[
|
||||
'key' => 'php',
|
||||
'name' => 'PHP',
|
||||
'version' => '2.3.0',
|
||||
'version' => '2.3.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-php',
|
||||
'package' => 'https://packagist.org/packages/appwrite/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -323,7 +323,7 @@ return [
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'beta' => false,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_SERVER,
|
||||
|
||||
@@ -36,8 +36,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',
|
||||
],
|
||||
|
||||
+60
-14
@@ -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' => '',
|
||||
],
|
||||
];
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -149,6 +149,15 @@ return [
|
||||
'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' => ''
|
||||
]
|
||||
],
|
||||
],
|
||||
|
||||
+607
-617
File diff suppressed because it is too large
Load Diff
@@ -424,7 +424,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 +443,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 +458,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'];
|
||||
|
||||
+1548
-305
File diff suppressed because it is too large
Load Diff
+244
-275
@@ -2,10 +2,8 @@
|
||||
|
||||
use Ahc\Jwt\JWT;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Validator\UID;
|
||||
use Appwrite\Database\Validator\CustomId;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\Storage\Validator\File;
|
||||
use Utopia\Storage\Validator\FileExt;
|
||||
@@ -14,6 +12,11 @@ use Utopia\Storage\Validator\Upload;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Task\Validator\Cron;
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Assoc;
|
||||
use Utopia\Validator\Text;
|
||||
@@ -38,6 +41,7 @@ App::post('/v1/functions')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_FUNCTION)
|
||||
->param('functionId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
|
||||
->param('execute', [], new ArrayList(new Text(64)), 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
|
||||
@@ -46,16 +50,15 @@ App::post('/v1/functions')
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, 900), 'Function maximum execution time in seconds.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$function = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_FUNCTIONS,
|
||||
'$permissions' => [
|
||||
'execute' => $execute,
|
||||
],
|
||||
$functionId = ($functionId == 'unique()') ? $dbForInternal->getId() : $functionId;
|
||||
$function = $dbForInternal->createDocument('functions', new Document([
|
||||
'$id' => $functionId,
|
||||
'execute' => $execute,
|
||||
'dateCreated' => time(),
|
||||
'dateUpdated' => time(),
|
||||
'status' => 'disabled',
|
||||
@@ -65,19 +68,14 @@ App::post('/v1/functions')
|
||||
'vars' => $vars,
|
||||
'events' => $events,
|
||||
'schedule' => $schedule,
|
||||
'schedulePrevious' => null,
|
||||
'scheduleNext' => null,
|
||||
'schedulePrevious' => 0,
|
||||
'scheduleNext' => 0,
|
||||
'timeout' => $timeout,
|
||||
]);
|
||||
'search' => implode(' ', [$functionId, $name, $runtime]),
|
||||
]));
|
||||
|
||||
if (false === $function) {
|
||||
throw new Exception('Failed saving function to DB', 500);
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($function, Response::MODEL_FUNCTION)
|
||||
;
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($function, Response::MODEL_FUNCTION);
|
||||
});
|
||||
|
||||
App::get('/v1/functions')
|
||||
@@ -94,26 +92,32 @@ App::get('/v1/functions')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderType' => $orderType,
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_FUNCTIONS,
|
||||
],
|
||||
]);
|
||||
if (!empty($cursor)) {
|
||||
$cursorFunction = $dbForInternal->getDocument('functions', $cursor);
|
||||
|
||||
if ($cursorFunction->isEmpty()) {
|
||||
throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'sum' => $projectDB->getSum(),
|
||||
'functions' => $results
|
||||
'functions' => $dbForInternal->find('functions', $queries, $limit, $offset, [], [$orderType], $cursorFunction ?? null, $cursorDirection),
|
||||
'sum' => $dbForInternal->count('functions', $queries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_FUNCTION_LIST);
|
||||
});
|
||||
|
||||
@@ -130,14 +134,14 @@ App::get('/v1/functions/:functionId')
|
||||
->label('sdk.response.model', Response::MODEL_FUNCTION)
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($functionId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
@@ -151,118 +155,83 @@ App::get('/v1/functions/:functionId/usage')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'getUsage')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_USAGE_FUNCTIONS)
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d']), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('register')
|
||||
->action(function ($functionId, $range, $response, $project, $projectDB, $register) {
|
||||
->action(function ($functionId, $range, $response, $project, $dbForInternal, $register) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $consoleDB */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$usage = [];
|
||||
if(App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$period = [
|
||||
'24h' => [
|
||||
'start' => DateTime::createFromFormat('U', \strtotime('-24 hours')),
|
||||
'end' => DateTime::createFromFormat('U', \strtotime('+1 hour')),
|
||||
'group' => '30m',
|
||||
'period' => '30m',
|
||||
'limit' => 48,
|
||||
],
|
||||
'7d' => [
|
||||
'start' => DateTime::createFromFormat('U', \strtotime('-7 days')),
|
||||
'end' => DateTime::createFromFormat('U', \strtotime('now')),
|
||||
'group' => '1d',
|
||||
'period' => '1d',
|
||||
'limit' => 7,
|
||||
],
|
||||
'30d' => [
|
||||
'start' => DateTime::createFromFormat('U', \strtotime('-30 days')),
|
||||
'end' => DateTime::createFromFormat('U', \strtotime('now')),
|
||||
'group' => '1d',
|
||||
'period' => '1d',
|
||||
'limit' => 30,
|
||||
],
|
||||
'90d' => [
|
||||
'start' => DateTime::createFromFormat('U', \strtotime('-90 days')),
|
||||
'end' => DateTime::createFromFormat('U', \strtotime('now')),
|
||||
'group' => '1d',
|
||||
'period' => '1d',
|
||||
'limit' => 90,
|
||||
],
|
||||
];
|
||||
|
||||
$metrics = [
|
||||
"functions.$functionId.executions",
|
||||
"functions.$functionId.failures",
|
||||
"functions.$functionId.compute"
|
||||
];
|
||||
|
||||
$stats = [];
|
||||
|
||||
Authorization::skip(function() use ($dbForInternal, $period, $range, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
$requestDocs = $dbForInternal->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period[$range]['period']]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $period[$range]['limit'], 0, ['time'], [Database::ORDER_DESC]);
|
||||
|
||||
$client = $register->get('influxdb');
|
||||
|
||||
$executions = [];
|
||||
$failures = [];
|
||||
$compute = [];
|
||||
|
||||
if ($client) {
|
||||
$start = $period[$range]['start']->format(DateTime::RFC3339);
|
||||
$end = $period[$range]['end']->format(DateTime::RFC3339);
|
||||
$database = $client->selectDB('telegraf');
|
||||
|
||||
// Executions
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_executions_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' AND "functionId"=\''.$function->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
|
||||
$points = $result->getPoints();
|
||||
|
||||
foreach ($points as $point) {
|
||||
$executions[] = [
|
||||
'value' => (!empty($point['value'])) ? $point['value'] : 0,
|
||||
'date' => \strtotime($point['time']),
|
||||
];
|
||||
}
|
||||
|
||||
// Failures
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_executions_all" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' AND "functionId"=\''.$function->getId().'\' AND "functionStatus"=\'failed\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
|
||||
$points = $result->getPoints();
|
||||
|
||||
foreach ($points as $point) {
|
||||
$failures[] = [
|
||||
'value' => (!empty($point['value'])) ? $point['value'] : 0,
|
||||
'date' => \strtotime($point['time']),
|
||||
];
|
||||
}
|
||||
|
||||
// Compute
|
||||
$result = $database->query('SELECT sum(value) AS "value" FROM "appwrite_usage_executions_time" WHERE time > \''.$start.'\' AND time < \''.$end.'\' AND "metric_type"=\'counter\' AND "project"=\''.$project->getId().'\' AND "functionId"=\''.$function->getId().'\' GROUP BY time('.$period[$range]['group'].') FILL(null)');
|
||||
$points = $result->getPoints();
|
||||
|
||||
foreach ($points as $point) {
|
||||
$compute[] = [
|
||||
'value' => round((!empty($point['value'])) ? $point['value'] / 1000 : 0, 2), // minutes
|
||||
'date' => \strtotime($point['time']),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$response->json([
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
$stats[$metric][] = [
|
||||
'value' => $requestDoc->getAttribute('value'),
|
||||
'date' => $requestDoc->getAttribute('time'),
|
||||
];
|
||||
}
|
||||
$stats[$metric] = array_reverse($stats[$metric]);
|
||||
}
|
||||
});
|
||||
|
||||
$usage = new Document([
|
||||
'range' => $range,
|
||||
'executions' => [
|
||||
'data' => $executions,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $executions)),
|
||||
],
|
||||
'failures' => [
|
||||
'data' => $failures,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $failures)),
|
||||
],
|
||||
'compute' => [
|
||||
'data' => $compute,
|
||||
'total' => \array_sum(\array_map(function ($item) {
|
||||
return $item['value'];
|
||||
}, $compute)),
|
||||
],
|
||||
'functions.executions' => $stats["functions.$functionId.executions"],
|
||||
'functions.failures' => $stats["functions.$functionId.failures"],
|
||||
'functions.compute' => $stats["functions.$functionId.compute"]
|
||||
]);
|
||||
} else {
|
||||
$response->json([]);
|
||||
}
|
||||
|
||||
$response->dynamic($usage, Response::MODEL_USAGE_FUNCTIONS);
|
||||
});
|
||||
|
||||
App::put('/v1/functions/:functionId')
|
||||
@@ -285,39 +254,34 @@ App::put('/v1/functions/:functionId')
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, 900), 'Function maximum execution time in seconds.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('project')
|
||||
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $projectDB, $project) {
|
||||
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForInternal, $project) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$original = $function->getAttribute('schedule', '');
|
||||
$cron = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? new CronExpression($schedule) : null;
|
||||
$next = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : null;
|
||||
$next = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
|
||||
|
||||
$function = $projectDB->updateDocument(array_merge($function->getArrayCopy(), [
|
||||
'$permissions' => [
|
||||
'execute' => $execute,
|
||||
],
|
||||
$function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
|
||||
'execute' => $execute,
|
||||
'dateUpdated' => time(),
|
||||
'name' => $name,
|
||||
'vars' => $vars,
|
||||
'events' => $events,
|
||||
'schedule' => $schedule,
|
||||
'scheduleNext' => $next,
|
||||
'scheduleNext' => (int)$next,
|
||||
'timeout' => $timeout,
|
||||
]));
|
||||
|
||||
if (false === $function) {
|
||||
throw new Exception('Failed saving function to DB', 500);
|
||||
}
|
||||
'search' => implode(' ', [$functionId, $name, $function->getAttribute('runtime')]),
|
||||
])));
|
||||
|
||||
if ($next && $schedule !== $original) {
|
||||
ResqueScheduler::enqueueAt($next, 'v1-functions', 'FunctionsV1', [
|
||||
@@ -347,14 +311,14 @@ App::patch('/v1/functions/:functionId/tag')
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('tag', '', new UID(), 'Tag unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('project')
|
||||
->action(function ($functionId, $tag, $response, $projectDB, $project) {
|
||||
->action(function ($functionId, $tag, $response, $dbForInternal, $project) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
$ch = \curl_init();
|
||||
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor:8080/v1/tag");
|
||||
@@ -404,15 +368,14 @@ App::delete('/v1/functions/:functionId')
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('deletes')
|
||||
->action(function ($functionId, $response, $project, $projectDB, $deletes) {
|
||||
->action(function ($functionId, $response, $dbForInternal, $deletes) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
// Request executor to delete tag containers
|
||||
$ch = \curl_init();
|
||||
@@ -446,17 +409,17 @@ App::delete('/v1/functions/:functionId')
|
||||
|
||||
\curl_close($ch);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
if (!$projectDB->deleteDocument($function->getId())) {
|
||||
if (!$dbForInternal->deleteDocument('functions', $function->getId())) {
|
||||
throw new Exception('Failed to remove function from DB', 500);
|
||||
}
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $function->getArrayCopy())
|
||||
->setParam('document', $function)
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
@@ -481,17 +444,17 @@ App::post('/v1/functions/:functionId/tags')
|
||||
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($functionId, $entrypoint, $file, $request, $response, $projectDB, $usage) {
|
||||
->action(function ($functionId, $command, $file, $request, $response, $dbForInternal, $usage) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
@@ -530,35 +493,29 @@ App::post('/v1/functions/:functionId/tags')
|
||||
throw new Exception('Failed moving file', 500);
|
||||
}
|
||||
|
||||
$tag = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_TAGS,
|
||||
'$permissions' => [
|
||||
'read' => [],
|
||||
'write' => [],
|
||||
],
|
||||
$tagId = $dbForInternal->getId();
|
||||
$tag = $dbForInternal->createDocument('tags', new Document([
|
||||
'$id' => $tagId,
|
||||
'$read' => [],
|
||||
'$write' => [],
|
||||
'functionId' => $function->getId(),
|
||||
'dateCreated' => time(),
|
||||
'entrypoint' => $entrypoint,
|
||||
'path' => $path,
|
||||
'size' => $size,
|
||||
'search' => implode(' ', [$tagId, $command]),
|
||||
'status' => 'pending',
|
||||
'builtPath' => '',
|
||||
'buildStdout' => '',
|
||||
'buildStderr' => ''
|
||||
]);
|
||||
|
||||
if (false === $tag) {
|
||||
throw new Exception('Failed saving tag to DB', 500);
|
||||
}
|
||||
]));
|
||||
|
||||
$usage
|
||||
->setParam('storage', $tag->getAttribute('size', 0))
|
||||
;
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($tag, Response::MODEL_TAG)
|
||||
;
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($tag, Response::MODEL_TAG);
|
||||
});
|
||||
|
||||
App::get('/v1/functions/:functionId/tags')
|
||||
@@ -576,33 +533,43 @@ App::get('/v1/functions/:functionId/tags')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the tag used as the starting point for the query, excluding the tag itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($functionId, $search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderType' => $orderType,
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_TAGS,
|
||||
'functionId='.$function->getId(),
|
||||
],
|
||||
]);
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorTag = $dbForInternal->getDocument('tags', $cursor);
|
||||
|
||||
if ($cursorTag->isEmpty()) {
|
||||
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]);
|
||||
|
||||
$results = $dbForInternal->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('tags', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'sum' => $projectDB->getSum(),
|
||||
'tags' => $results
|
||||
'tags' => $results,
|
||||
'sum' => $sum,
|
||||
]), Response::MODEL_TAG_LIST);
|
||||
});
|
||||
|
||||
@@ -620,24 +587,24 @@ App::get('/v1/functions/:functionId/tags/:tagId')
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('tagId', '', new UID(), 'Tag unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($functionId, $tagId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $tagId, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$tag = $projectDB->getDocument($tagId);
|
||||
$tag = $dbForInternal->getDocument('tags', $tagId);
|
||||
|
||||
if ($tag->getAttribute('functionId') !== $function->getId()) {
|
||||
throw new Exception('Tag not found', 404);
|
||||
}
|
||||
|
||||
if (empty($tag->getId()) || Database::SYSTEM_COLLECTION_TAGS != $tag->getCollection()) {
|
||||
if ($tag->isEmpty()) {
|
||||
throw new Exception('Tag not found', 404);
|
||||
}
|
||||
|
||||
@@ -658,27 +625,26 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('tagId', '', new UID(), 'Tag unique ID.')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($functionId, $tagId, $response, $project, $projectDB, $usage) {
|
||||
->action(function ($functionId, $tagId, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$tag = $projectDB->getDocument($tagId);
|
||||
$tag = $dbForInternal->getDocument('tags', $tagId);
|
||||
|
||||
if ($tag->getAttribute('functionId') !== $function->getId()) {
|
||||
throw new Exception('Tag not found', 404);
|
||||
}
|
||||
|
||||
if (empty($tag->getId()) || Database::SYSTEM_COLLECTION_TAGS != $tag->getCollection()) {
|
||||
if ($tag->isEmpty()) {
|
||||
throw new Exception('Tag not found', 404);
|
||||
}
|
||||
|
||||
@@ -717,19 +683,15 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
|
||||
$device = Storage::getDevice('functions');
|
||||
|
||||
if ($device->delete($tag->getAttribute('path', ''))) {
|
||||
if (!$projectDB->deleteDocument($tag->getId())) {
|
||||
if (!$dbForInternal->deleteDocument('tags', $tag->getId())) {
|
||||
throw new Exception('Failed to remove tag from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
if($function->getAttribute('tag') === $tag->getId()) { // Reset function tag
|
||||
$function = $projectDB->updateDocument(array_merge($function->getArrayCopy(), [
|
||||
$function = $dbForInternal->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
|
||||
'tag' => '',
|
||||
]));
|
||||
|
||||
if (false === $function) {
|
||||
throw new Exception('Failed saving function to DB', 500);
|
||||
}
|
||||
])));
|
||||
}
|
||||
|
||||
$usage
|
||||
@@ -758,29 +720,29 @@ App::post('/v1/functions/:functionId/executions')
|
||||
->param('async', 1, new Range(0, 1), 'Execute code asynchronously. Pass 1 for true, 0 for false. Default value is 1.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('user')
|
||||
->action(function ($functionId, $data, $async, $response, $project, $projectDB, $user) {
|
||||
->action(function ($functionId, $data, $async, $response, $project, $dbForInternal, $user) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$tag = $projectDB->getDocument($function->getAttribute('tag'));
|
||||
$tag = $dbForInternal->getDocument('tags', $function->getAttribute('tag'));
|
||||
|
||||
if ($tag->getAttribute('functionId') !== $function->getId()) {
|
||||
throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404);
|
||||
}
|
||||
|
||||
if (empty($tag->getId()) || Database::SYSTEM_COLLECTION_TAGS != $tag->getCollection()) {
|
||||
if ($tag->isEmpty()) {
|
||||
throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404);
|
||||
}
|
||||
|
||||
@@ -788,41 +750,39 @@ App::post('/v1/functions/:functionId/executions')
|
||||
|
||||
$validator = new Authorization($function, 'execute');
|
||||
|
||||
if (!$validator->isValid($function->getPermissions())) { // Check if user has write access to execute function
|
||||
if (!$validator->isValid($function->getAttribute('execute'))) { // Check if user has write access to execute function
|
||||
throw new Exception($validator->getDescription(), 401);
|
||||
}
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$execution = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_EXECUTIONS,
|
||||
'$permissions' => [
|
||||
'read' => (!empty($user->getId())) ? ['user:' . $user->getId()] : [],
|
||||
'write' => [],
|
||||
],
|
||||
$executionId = $dbForInternal->getId();
|
||||
|
||||
$execution = $dbForInternal->createDocument('executions', new Document([
|
||||
'$id' => $executionId,
|
||||
'$read' => (!$user->isEmpty()) ? ['user:' . $user->getId()] : [],
|
||||
'$write' => [],
|
||||
'dateCreated' => time(),
|
||||
'functionId' => $function->getId(),
|
||||
'tagId' => $tag->getId(),
|
||||
'trigger' => 'http', // http / schedule / event
|
||||
'status' => 'waiting', // waiting / processing / completed / failed
|
||||
'exitCode' => 0,
|
||||
'stdout' => '',
|
||||
'stderr' => '',
|
||||
'time' => 0
|
||||
]);
|
||||
'time' => 0.0,
|
||||
'search' => implode(' ', [$functionId, $executionId]),
|
||||
]));
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
if (false === $execution) {
|
||||
throw new Exception('Failed saving execution to DB', 500);
|
||||
}
|
||||
|
||||
$jwt = ''; // initialize
|
||||
if (!empty($user->getId())) { // If userId exists, generate a JWT for function
|
||||
|
||||
if (!$user->isEmpty()) { // If userId exists, generate a JWT for function
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$current = new Document();
|
||||
|
||||
foreach ($sessions as $session) { /** @var Appwrite\Database\Document $session */
|
||||
foreach ($sessions as $session) { /** @var Utopia\Database\Document $session */
|
||||
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
|
||||
$current = $session;
|
||||
}
|
||||
@@ -849,9 +809,9 @@ App::post('/v1/functions/:functionId/executions')
|
||||
'jwt' => $jwt
|
||||
]);
|
||||
|
||||
return $response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($execution, Response::MODEL_EXECUTION);
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($execution, Response::MODEL_EXECUTION);
|
||||
return $response;
|
||||
}
|
||||
// Directly execute function.
|
||||
$ch = \curl_init();
|
||||
@@ -901,38 +861,47 @@ App::get('/v1/functions/:functionId/executions')
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_EXECUTION_LIST)
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($functionId, $search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $limit, $offset, $search, $cursor, $cursorDirection, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
Authorization::disable();
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
Authorization::reset();
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
$function = Authorization::skip(function() use ($dbForInternal, $functionId) {
|
||||
return $dbForInternal->getDocument('functions', $functionId);
|
||||
});
|
||||
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderType' => $orderType,
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_EXECUTIONS,
|
||||
'functionId='.$function->getId(),
|
||||
],
|
||||
]);
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorExecution = $dbForInternal->getDocument('executions', $cursor);
|
||||
|
||||
if ($cursorExecution->isEmpty()) {
|
||||
throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [
|
||||
new Query('functionId', Query::TYPE_EQUAL, [$function->getId()])
|
||||
];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('executions', $queries, $limit, $offset, [], [Database::ORDER_DESC], $cursorExecution ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('executions', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'sum' => $projectDB->getSum(),
|
||||
'executions' => $results
|
||||
'executions' => $results,
|
||||
'sum' => $sum,
|
||||
]), Response::MODEL_EXECUTION_LIST);
|
||||
});
|
||||
|
||||
@@ -950,26 +919,26 @@ App::get('/v1/functions/:functionId/executions/:executionId')
|
||||
->param('functionId', '', new UID(), 'Function unique ID.')
|
||||
->param('executionId', '', new UID(), 'Execution unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($functionId, $executionId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($functionId, $executionId, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
Authorization::disable();
|
||||
$function = $projectDB->getDocument($functionId);
|
||||
$function = $dbForInternal->getDocument('functions', $functionId);
|
||||
Authorization::reset();
|
||||
|
||||
if (empty($function->getId()) || Database::SYSTEM_COLLECTION_FUNCTIONS != $function->getCollection()) {
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
}
|
||||
|
||||
$execution = $projectDB->getDocument($executionId);
|
||||
$execution = $dbForInternal->getDocument('executions', $executionId);
|
||||
|
||||
if ($execution->getAttribute('functionId') !== $function->getId()) {
|
||||
throw new Exception('Execution not found', 404);
|
||||
}
|
||||
|
||||
if (empty($execution->getId()) || Database::SYSTEM_COLLECTION_EXECUTIONS != $execution->getCollection()) {
|
||||
if ($execution->isEmpty()) {
|
||||
throw new Exception('Execution not found', 404);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,21 +133,6 @@ App::get('/v1/health/queue/webhooks')
|
||||
$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']);
|
||||
|
||||
App::get('/v1/health/queue/logs')
|
||||
->desc('Get Logs Queue')
|
||||
->groups(['api', 'health'])
|
||||
@@ -266,7 +251,7 @@ App::get('/v1/health/anti-virus')
|
||||
'status' => (@$antiVirus->ping()) ? 'online' : 'offline',
|
||||
'version' => @$antiVirus->version(),
|
||||
]);
|
||||
} catch( \Exception $e) {
|
||||
} catch (Throwable $e) {
|
||||
$response->json([
|
||||
'status' => 'offline',
|
||||
'version' => '',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Database\Document;
|
||||
use Utopia\Database\Document;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
+533
-860
File diff suppressed because it is too large
Load Diff
+293
-148
@@ -10,9 +10,10 @@ use Utopia\Validator\HexColor;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
use Appwrite\ClamAV\Network;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\UID;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Validator\CustomId;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\Storage\Validator\File;
|
||||
use Utopia\Storage\Validator\FileSize;
|
||||
@@ -22,6 +23,8 @@ use Utopia\Image\Image;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
App::post('/v1/storage/files')
|
||||
->desc('Create File')
|
||||
@@ -37,22 +40,23 @@ App::post('/v1/storage/files')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_FILE)
|
||||
->param('fileId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('file', [], new File(), 'Binary file.', false)
|
||||
->param('read', null, new ArrayList(new Text(64)), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->param('write', null, new ArrayList(new Text(64)), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('user')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($file, $read, $write, $request, $response, $projectDB, $user, $audits, $usage) {
|
||||
->action(function ($fileId, $file, $read, $write, $request, $response, $dbForInternal, $user, $audits, $usage) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$file = $request->getFiles('file');
|
||||
|
||||
@@ -90,7 +94,7 @@ App::post('/v1/storage/files')
|
||||
// Save to storage
|
||||
$size = $device->getFileSize($file['tmp_name']);
|
||||
$path = $device->getPath(\uniqid().'.'.\pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
|
||||
|
||||
if (!$device->upload($file['tmp_name'], $path)) { // TODO deprecate 'upload' and replace with 'move'
|
||||
throw new Exception('Failed moving file', 500);
|
||||
}
|
||||
@@ -120,46 +124,42 @@ App::post('/v1/storage/files')
|
||||
}
|
||||
|
||||
$sizeActual = $device->getFileSize($path);
|
||||
|
||||
$file = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_FILES,
|
||||
'$permissions' => [
|
||||
'read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
|
||||
'write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
|
||||
],
|
||||
|
||||
$fileId = ($fileId == 'unique()') ? $dbForInternal->getId() : $fileId;
|
||||
$file = $dbForInternal->createDocument('files', new Document([
|
||||
'$id' => $fileId,
|
||||
'$read' => (is_null($read) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $read ?? [], // By default set read permissions for user
|
||||
'$write' => (is_null($write) && !$user->isEmpty()) ? ['user:'.$user->getId()] : $write ?? [], // By default set write permissions for user
|
||||
'dateCreated' => \time(),
|
||||
'folderId' => '',
|
||||
'name' => $file['name'],
|
||||
'bucketId' => '',
|
||||
'name' => $file['name'] ?? '',
|
||||
'path' => $path,
|
||||
'signature' => $device->getFileHash($path),
|
||||
'mimeType' => $mimeType,
|
||||
'sizeOriginal' => $size,
|
||||
'sizeActual' => $sizeActual,
|
||||
'algorithm' => $compressor->getName(),
|
||||
'token' => \bin2hex(\random_bytes(64)),
|
||||
'comment' => '',
|
||||
'fileOpenSSLVersion' => '1',
|
||||
'fileOpenSSLCipher' => OpenSSL::CIPHER_AES_128_GCM,
|
||||
'fileOpenSSLTag' => \bin2hex($tag),
|
||||
'fileOpenSSLIV' => \bin2hex($iv),
|
||||
]);
|
||||
|
||||
if (false === $file) {
|
||||
throw new Exception('Failed saving file to DB', 500);
|
||||
}
|
||||
'openSSLVersion' => '1',
|
||||
'openSSLCipher' => OpenSSL::CIPHER_AES_128_GCM,
|
||||
'openSSLTag' => \bin2hex($tag),
|
||||
'openSSLIV' => \bin2hex($iv),
|
||||
'search' => implode(' ', [$fileId, $file['name'] ?? '',]),
|
||||
]));
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.files.create')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
->setParam('resource', 'file/'.$file->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('storage', $sizeActual)
|
||||
->setParam('storage.files.create', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($file, Response::MODEL_FILE)
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($file, Response::MODEL_FILE);
|
||||
;
|
||||
});
|
||||
|
||||
@@ -177,26 +177,39 @@ App::get('/v1/storage/files')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the file used as the starting point for the query, excluding the file itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderType' => $orderType,
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_FILES,
|
||||
],
|
||||
]);
|
||||
if (!empty($cursor)) {
|
||||
$cursorFile = $dbForInternal->getDocument('files', $cursor);
|
||||
|
||||
if ($cursorFile->isEmpty()) {
|
||||
throw new Exception("File '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.read', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'sum' => $projectDB->getSum(),
|
||||
'files' => $results
|
||||
'files' => $dbForInternal->find('files', $queries, $limit, $offset, [], [$orderType], $cursorFile ?? null, $cursorDirection),
|
||||
'sum' => $dbForInternal->count('files', $queries, APP_LIMIT_COUNT),
|
||||
]), Response::MODEL_FILE_LIST);
|
||||
});
|
||||
|
||||
@@ -213,17 +226,22 @@ App::get('/v1/storage/files/:fileId')
|
||||
->label('sdk.response.model', Response::MODEL_FILE)
|
||||
->param('fileId', '', new UID(), 'File unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($fileId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($fileId, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$file = $dbForInternal->getDocument('files', $fileId);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
if (empty($file->getId())) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.read', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
$response->dynamic($file, Response::MODEL_FILE);
|
||||
});
|
||||
|
||||
@@ -253,12 +271,14 @@ App::get('/v1/storage/files/:fileId/preview')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('projectDB')
|
||||
->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output, $request, $response, $project, $dbForInternal, $usage) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $stats */
|
||||
|
||||
$storage = 'files';
|
||||
|
||||
@@ -281,16 +301,16 @@ App::get('/v1/storage/files/:fileId/preview')
|
||||
$date = \date('D, d M Y H:i:s', \time() + (60 * 60 * 24 * 45)).' GMT'; // 45 days cache
|
||||
$key = \md5($fileId.$width.$height.$gravity.$quality.$borderWidth.$borderColor.$borderRadius.$opacity.$rotation.$background.$storage.$output);
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$file = $dbForInternal->getDocument('files', $fileId);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
if (empty($file->getId())) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$path = $file->getAttribute('path');
|
||||
$type = \strtolower(\pathinfo($path, PATHINFO_EXTENSION));
|
||||
$algorithm = $file->getAttribute('algorithm');
|
||||
$cipher = $file->getAttribute('fileOpenSSLCipher');
|
||||
$cipher = $file->getAttribute('openSSLCipher');
|
||||
$mime = $file->getAttribute('mimeType');
|
||||
|
||||
if (!\in_array($mime, $inputs)) {
|
||||
@@ -328,11 +348,11 @@ App::get('/v1/storage/files/:fileId/preview')
|
||||
if (!empty($cipher)) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
$file->getAttribute('openSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('openSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
\hex2bin($file->getAttribute('openSSLIV')),
|
||||
\hex2bin($file->getAttribute('openSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -371,6 +391,11 @@ App::get('/v1/storage/files/:fileId/preview')
|
||||
|
||||
$cache->save($key, $data);
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.read', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
$response
|
||||
->setContentType($outputs[$output])
|
||||
->addHeader('Expires', $date)
|
||||
@@ -394,14 +419,16 @@ App::get('/v1/storage/files/:fileId/download')
|
||||
->label('sdk.methodType', 'location')
|
||||
->param('fileId', '', new UID(), 'File unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($fileId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($fileId, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$file = $dbForInternal->getDocument('files', $fileId);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
if (empty($file->getId())) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
@@ -416,19 +443,24 @@ App::get('/v1/storage/files/:fileId/download')
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
if (!empty($file->getAttribute('openSSLCipher'))) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
$file->getAttribute('openSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('openSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
\hex2bin($file->getAttribute('openSSLIV')),
|
||||
\hex2bin($file->getAttribute('openSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
$source = $compressor->decompress($source);
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.read', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
// Response
|
||||
$response
|
||||
->setContentType($file->getAttribute('mimeType'))
|
||||
@@ -452,15 +484,17 @@ App::get('/v1/storage/files/:fileId/view')
|
||||
->label('sdk.methodType', 'location')
|
||||
->param('fileId', '', new UID(), 'File unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($fileId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->inject('usage')
|
||||
->action(function ($fileId, $response, $dbForInternal, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$file = $dbForInternal->getDocument('files', $fileId);
|
||||
$mimes = Config::getParam('storage-mimes');
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
if (empty($file->getId())) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
@@ -481,20 +515,25 @@ App::get('/v1/storage/files/:fileId/view')
|
||||
|
||||
$source = $device->read($path);
|
||||
|
||||
if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
if (!empty($file->getAttribute('openSSLCipher'))) { // Decrypt
|
||||
$source = OpenSSL::decrypt(
|
||||
$source,
|
||||
$file->getAttribute('fileOpenSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
$file->getAttribute('openSSLCipher'),
|
||||
App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('openSSLVersion')),
|
||||
0,
|
||||
\hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
\hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
\hex2bin($file->getAttribute('openSSLIV')),
|
||||
\hex2bin($file->getAttribute('openSSLTag'))
|
||||
);
|
||||
}
|
||||
|
||||
$output = $compressor->decompress($source);
|
||||
$fileName = $file->getAttribute('name', '');
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.read', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
// Response
|
||||
$response
|
||||
->setContentType($contentType)
|
||||
@@ -523,34 +562,34 @@ App::put('/v1/storage/files/:fileId')
|
||||
->param('read', [], new ArrayList(new Text(64)), 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->param('write', [], new ArrayList(new Text(64)), 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('audits')
|
||||
->action(function ($fileId, $read, $write, $response, $projectDB, $audits) {
|
||||
->inject('usage')
|
||||
->action(function ($fileId, $read, $write, $response, $dbForInternal, $audits, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$file = $dbForInternal->getDocument('files', $fileId);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
if (empty($file->getId())) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$file = $projectDB->updateDocument(\array_merge($file->getArrayCopy(), [
|
||||
'$permissions' => [
|
||||
'read' => $read,
|
||||
'write' => $write,
|
||||
],
|
||||
'folderId' => '',
|
||||
]));
|
||||
|
||||
if (false === $file) {
|
||||
throw new Exception('Failed saving file to DB', 500);
|
||||
}
|
||||
$file = $dbForInternal->updateDocument('files', $fileId, new Document(\array_merge($file->getArrayCopy(), [
|
||||
'$read' => $read,
|
||||
'$write' => $write,
|
||||
'bucketId' => '',
|
||||
])));
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.files.update')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
->setParam('resource', 'file/'.$file->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.update', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
$response->dynamic($file, Response::MODEL_FILE);
|
||||
@@ -569,38 +608,40 @@ App::delete('/v1/storage/files/:fileId')
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->param('fileId', '', new UID(), 'File unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('events')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($fileId, $response, $projectDB, $events, $audits, $usage) {
|
||||
->action(function ($fileId, $response, $dbForInternal, $events, $audits, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$file = $projectDB->getDocument($fileId);
|
||||
$file = $dbForInternal->getDocument('files', $fileId);
|
||||
|
||||
if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
if (empty($file->getId())) {
|
||||
throw new Exception('File not found', 404);
|
||||
}
|
||||
|
||||
$device = Storage::getDevice('files');
|
||||
|
||||
if ($device->delete($file->getAttribute('path', ''))) {
|
||||
if (!$projectDB->deleteDocument($fileId)) {
|
||||
if (!$dbForInternal->deleteDocument('files', $fileId)) {
|
||||
throw new Exception('Failed to remove file from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.files.delete')
|
||||
->setParam('resource', 'storage/files/'.$file->getId())
|
||||
->setParam('resource', 'file/'.$file->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('storage', $file->getAttribute('size', 0) * -1)
|
||||
->setParam('storage.files.delete', 1)
|
||||
->setParam('bucketId', 'default')
|
||||
;
|
||||
|
||||
$events
|
||||
@@ -610,53 +651,157 @@ App::delete('/v1/storage/files/:fileId')
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
// App::get('/v1/storage/files/:fileId/scan')
|
||||
// ->desc('Scan Storage')
|
||||
// ->groups(['api', 'storage'])
|
||||
// ->label('scope', 'root')
|
||||
// ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
// ->label('sdk.namespace', 'storage')
|
||||
// ->label('sdk.method', 'getFileScan')
|
||||
// ->label('sdk.hide', true)
|
||||
// ->param('fileId', '', new UID(), 'File unique ID.')
|
||||
// ->param('storage', 'files', new WhiteList(['files']);})
|
||||
// ->action(
|
||||
// function ($fileId, $storage) use ($response, $request, $projectDB) {
|
||||
// $file = $projectDB->getDocument($fileId);
|
||||
App::get('/v1/storage/usage')
|
||||
->desc('Get usage stats for storage')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'getUsage')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_USAGE_STORAGE)
|
||||
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($range, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
// if (empty($file->getId()) || Database::SYSTEM_COLLECTION_FILES != $file->getCollection()) {
|
||||
// throw new Exception('File not found', 404);
|
||||
// }
|
||||
$usage = [];
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$period = [
|
||||
'24h' => [
|
||||
'period' => '30m',
|
||||
'limit' => 48,
|
||||
],
|
||||
'7d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 7,
|
||||
],
|
||||
'30d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 30,
|
||||
],
|
||||
'90d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 90,
|
||||
],
|
||||
];
|
||||
|
||||
// $path = $file->getAttribute('path', '');
|
||||
$metrics = [
|
||||
"storage.total",
|
||||
"storage.files.count"
|
||||
];
|
||||
|
||||
// if (!file_exists($path)) {
|
||||
// throw new Exception('File not found in '.$path, 404);
|
||||
// }
|
||||
$stats = [];
|
||||
|
||||
// $compressor = new GZIP();
|
||||
// $device = Storage::getDevice($storage);
|
||||
Authorization::skip(function() use ($dbForInternal, $period, $range, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
$requestDocs = $dbForInternal->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period[$range]['period']]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $period[$range]['limit'], 0, ['time'], [Database::ORDER_DESC]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
$stats[$metric][] = [
|
||||
'value' => $requestDoc->getAttribute('value'),
|
||||
'date' => $requestDoc->getAttribute('time'),
|
||||
];
|
||||
}
|
||||
$stats[$metric] = array_reverse($stats[$metric]);
|
||||
}
|
||||
});
|
||||
|
||||
// $source = $device->read($path);
|
||||
$usage = new Document([
|
||||
'range' => $range,
|
||||
'storage' => $stats['storage.total'],
|
||||
'files' => $stats['storage.files.count']
|
||||
]);
|
||||
}
|
||||
|
||||
// if (!empty($file->getAttribute('fileOpenSSLCipher'))) { // Decrypt
|
||||
// $source = OpenSSL::decrypt(
|
||||
// $source,
|
||||
// $file->getAttribute('fileOpenSSLCipher'),
|
||||
// App::getEnv('_APP_OPENSSL_KEY_V'.$file->getAttribute('fileOpenSSLVersion')),
|
||||
// 0,
|
||||
// hex2bin($file->getAttribute('fileOpenSSLIV')),
|
||||
// hex2bin($file->getAttribute('fileOpenSSLTag'))
|
||||
// );
|
||||
// }
|
||||
$response->dynamic($usage, Response::MODEL_USAGE_STORAGE);
|
||||
});
|
||||
|
||||
// $source = $compressor->decompress($source);
|
||||
App::get('/v1/storage/:bucketId/usage')
|
||||
->desc('Get usage stats for a storage bucket')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'getBucketUsage')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_USAGE_BUCKETS)
|
||||
->param('bucketId', '', new UID(), 'Bucket unique ID.')
|
||||
->param('range', '30d', new WhiteList(['24h', '7d', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($bucketId, $range, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
// $antiVirus = new Network('clamav', 3310);
|
||||
// TODO: Check if the storage bucket exists else throw 404
|
||||
|
||||
$usage = [];
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$period = [
|
||||
'24h' => [
|
||||
'period' => '30m',
|
||||
'limit' => 48,
|
||||
],
|
||||
'7d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 7,
|
||||
],
|
||||
'30d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 30,
|
||||
],
|
||||
'90d' => [
|
||||
'period' => '1d',
|
||||
'limit' => 90,
|
||||
],
|
||||
];
|
||||
|
||||
// //var_dump($antiVirus->ping());
|
||||
// //var_dump($antiVirus->version());
|
||||
// //var_dump($antiVirus->fileScan('/storage/uploads/app-1/5/9/f/e/59fecaed49645.pdf'));
|
||||
$metrics = [
|
||||
"storage.buckets.$bucketId.files.count",
|
||||
"storage.buckets.$bucketId.files.create",
|
||||
"storage.buckets.$bucketId.files.read",
|
||||
"storage.buckets.$bucketId.files.update",
|
||||
"storage.buckets.$bucketId.files.delete"
|
||||
];
|
||||
|
||||
// }
|
||||
// );
|
||||
$stats = [];
|
||||
|
||||
Authorization::skip(function() use ($dbForInternal, $period, $range, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
$requestDocs = $dbForInternal->find('stats', [
|
||||
new Query('period', Query::TYPE_EQUAL, [$period[$range]['period']]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $period[$range]['limit'], 0, ['time'], [Database::ORDER_DESC]);
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
$stats[$metric][] = [
|
||||
'value' => $requestDoc->getAttribute('value'),
|
||||
'date' => $requestDoc->getAttribute('time'),
|
||||
];
|
||||
}
|
||||
$stats[$metric] = array_reverse($stats[$metric]);
|
||||
}
|
||||
});
|
||||
|
||||
$usage = new Document([
|
||||
'range' => $range,
|
||||
'files.count' => $stats["storage.buckets.$bucketId.files.count"],
|
||||
'files.create' => $stats["storage.buckets.$bucketId.files.create"],
|
||||
'files.read' => $stats["storage.buckets.$bucketId.files.read"],
|
||||
'files.update' => $stats["storage.buckets.$bucketId.files.update"],
|
||||
'files.delete' => $stats["storage.buckets.$bucketId.files.delete"]
|
||||
]);
|
||||
}
|
||||
|
||||
$response->dynamic($usage, Response::MODEL_USAGE_BUCKETS);
|
||||
});
|
||||
+309
-287
@@ -1,24 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Config\Config;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Utopia\Validator\Text;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\Database;
|
||||
use Appwrite\Database\Document;
|
||||
use Appwrite\Database\Validator\UID;
|
||||
use Appwrite\Database\Validator\Authorization;
|
||||
use Appwrite\Database\Exception\Duplicate;
|
||||
use Appwrite\Database\Validator\Key;
|
||||
use Appwrite\Database\Validator\CustomId;
|
||||
use Appwrite\Detector\Detector;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Network\Validator\Host;
|
||||
use Utopia\App;
|
||||
use Utopia\Exception;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
|
||||
App::post('/v1/teams')
|
||||
->desc('Create Team')
|
||||
@@ -32,16 +34,17 @@ App::post('/v1/teams')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_TEAM)
|
||||
->param('teamId', '', new CustomId(), 'Unique Id. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', null, new Text(128), 'Team name. Max length: 128 chars.')
|
||||
->param('roles', ['owner'], new ArrayList(new Key()), 'Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.', true)
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('events')
|
||||
->action(function ($name, $roles, $response, $user, $projectDB, $events) {
|
||||
->action(function ($teamId, $name, $roles, $response, $user, $dbForInternal, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
Authorization::disable();
|
||||
@@ -49,30 +52,23 @@ App::post('/v1/teams')
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
$team = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_TEAMS,
|
||||
'$permissions' => [
|
||||
'read' => ['team:{self}'],
|
||||
'write' => ['team:{self}/owner'],
|
||||
],
|
||||
$teamId = $teamId == 'unique()' ? $dbForInternal->getId() : $teamId;
|
||||
$team = $dbForInternal->createDocument('teams', new Document([
|
||||
'$id' => $teamId ,
|
||||
'$read' => ['team:'.$teamId],
|
||||
'$write' => ['team:'.$teamId .'/owner'],
|
||||
'name' => $name,
|
||||
'sum' => ($isPrivilegedUser || $isAppUser) ? 0 : 1,
|
||||
'dateCreated' => \time(),
|
||||
]);
|
||||
'search' => implode(' ', [$teamId, $name]),
|
||||
]));
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
if (false === $team) {
|
||||
throw new Exception('Failed saving team to DB', 500);
|
||||
}
|
||||
|
||||
if (!$isPrivilegedUser && !$isAppUser) { // Don't add user on server mode
|
||||
$membership = new Document([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'$permissions' => [
|
||||
'read' => ['user:'.$user->getId(), 'team:'.$team->getId()],
|
||||
'write' => ['user:'.$user->getId(), 'team:'.$team->getId().'/owner'],
|
||||
],
|
||||
'$read' => ['user:'.$user->getId(), 'team:'.$team->getId()],
|
||||
'$write' => ['user:'.$user->getId(), 'team:'.$team->getId().'/owner'],
|
||||
'userId' => $user->getId(),
|
||||
'teamId' => $team->getId(),
|
||||
'roles' => $roles,
|
||||
@@ -82,24 +78,19 @@ App::post('/v1/teams')
|
||||
'secret' => '',
|
||||
]);
|
||||
|
||||
$membership = $dbForInternal->createDocument('memberships', $membership);
|
||||
|
||||
// Attach user to team
|
||||
$user->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND);
|
||||
|
||||
$user = $projectDB->updateDocument($user->getArrayCopy());
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
}
|
||||
|
||||
if (!empty($user->getId())) {
|
||||
$events->setParam('userId', $user->getId());
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($team, Response::MODEL_TEAM)
|
||||
;
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($team, Response::MODEL_TEAM);
|
||||
});
|
||||
|
||||
App::get('/v1/teams')
|
||||
@@ -116,26 +107,35 @@ App::get('/v1/teams')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the team used as the starting point for the query, excluding the team itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$results = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderType' => $orderType,
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_TEAMS,
|
||||
],
|
||||
]);
|
||||
if (!empty($cursor)) {
|
||||
$cursorTeam = $dbForInternal->getDocument('teams', $cursor);
|
||||
|
||||
if ($cursorTeam->isEmpty()) {
|
||||
throw new Exception("Team '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$queries = [];
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = new Query('search', Query::TYPE_SEARCH, [$search]);
|
||||
}
|
||||
|
||||
$results = $dbForInternal->find('teams', $queries, $limit, $offset, [], [$orderType], $cursorTeam ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('teams', $queries, APP_LIMIT_COUNT);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'sum' => $projectDB->getSum(),
|
||||
'teams' => $results
|
||||
'teams' => $results,
|
||||
'sum' => $sum,
|
||||
]), Response::MODEL_TEAM_LIST);
|
||||
});
|
||||
|
||||
@@ -152,14 +152,14 @@ App::get('/v1/teams/:teamId')
|
||||
->label('sdk.response.model', Response::MODEL_TEAM)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($teamId, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($teamId, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
@@ -181,25 +181,22 @@ App::put('/v1/teams/:teamId')
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('name', null, new Text(128), 'Team name. Max length: 128 chars.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($teamId, $name, $response, $projectDB) {
|
||||
->inject('dbForInternal')
|
||||
->action(function ($teamId, $name, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$team = $projectDB->updateDocument(\array_merge($team->getArrayCopy(), [
|
||||
'name' => $name,
|
||||
]));
|
||||
$team = $dbForInternal->updateDocument('teams', $team->getId(),$team
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('search', implode(' ', [$teamId, $name]))
|
||||
);
|
||||
|
||||
if (false === $team) {
|
||||
throw new Exception('Failed saving team to DB', 500);
|
||||
}
|
||||
|
||||
$response->dynamic($team, Response::MODEL_TEAM);
|
||||
});
|
||||
|
||||
@@ -216,21 +213,33 @@ App::delete('/v1/teams/:teamId')
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('events')
|
||||
->inject('deletes')
|
||||
->action(function ($teamId, $response, $projectDB, $events, $deletes) {
|
||||
->action(function ($teamId, $response, $dbForInternal, $events, $deletes) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
if (!$projectDB->deleteDocument($teamId)) {
|
||||
$memberships = $dbForInternal->find('memberships', [
|
||||
new Query('teamId', Query::TYPE_EQUAL, [$teamId]),
|
||||
], 2000, 0); // TODO fix members limit
|
||||
|
||||
// TODO delete all members individually from the user object
|
||||
foreach ($memberships as $membership) {
|
||||
if (!$dbForInternal->deleteDocument('memberships', $membership->getId())) {
|
||||
throw new Exception('Failed to remove membership for team from DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$dbForInternal->deleteDocument('teams', $teamId)) {
|
||||
throw new Exception('Failed to remove team from DB', 500);
|
||||
}
|
||||
|
||||
@@ -262,69 +271,48 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
->label('abuse-limit', 10)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('email', '', new Email(), 'New team member email.')
|
||||
->param('name', '', new Text(128), 'New team member name. Max length: 128 chars.', true)
|
||||
->param('roles', [], new ArrayList(new Key()), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.')
|
||||
->param('url', '', function ($clients) { return new Host($clients); }, 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false, ['clients']) // TODO add our own built-in confirm page
|
||||
->param('name', '', new Text(128), 'New team member name. Max length: 128 chars.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('locale')
|
||||
->inject('audits')
|
||||
->inject('mails')
|
||||
->action(function ($teamId, $email, $name, $roles, $url, $response, $project, $user, $projectDB, $locale, $audits, $mails) {
|
||||
->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForInternal, $locale, $audits, $mails) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503);
|
||||
}
|
||||
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
|
||||
|
||||
$email = \strtolower($email);
|
||||
$name = (empty($name)) ? $email : $name;
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$memberships = $projectDB->getCollection([
|
||||
'limit' => 2000,
|
||||
'offset' => 0,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'teamId='.$team->getId(),
|
||||
],
|
||||
]);
|
||||
|
||||
$invitee = $projectDB->getCollectionFirst([ // Get user by email address
|
||||
'limit' => 1,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
'email='.$email,
|
||||
],
|
||||
]);
|
||||
$invitee = $dbForInternal->findOne('users', [new Query('email', Query::TYPE_EQUAL, [$email])]); // Get user by email address
|
||||
|
||||
if (empty($invitee)) { // Create new user if no user with same email found
|
||||
|
||||
$limit = $project->getAttribute('usersAuthLimit', 0);
|
||||
|
||||
$limit = $project->getAttribute('auths', [])['limit'] ?? 0;
|
||||
|
||||
if ($limit !== 0 && $project->getId() !== 'console') { // check users limit, console invites are allways allowed.
|
||||
$projectDB->getCollection([ // Count users
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
],
|
||||
]);
|
||||
|
||||
$sum = $projectDB->getSum();
|
||||
|
||||
$sum = $dbForInternal->count('users', [], APP_LIMIT_USERS);
|
||||
|
||||
if($sum >= $limit) {
|
||||
throw new Exception('Project registration is restricted. Contact your administrator for more information.', 501);
|
||||
}
|
||||
@@ -333,15 +321,14 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
Authorization::disable();
|
||||
|
||||
try {
|
||||
$invitee = $projectDB->createDocument([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_USERS,
|
||||
'$permissions' => [
|
||||
'read' => ['user:{self}', '*'],
|
||||
'write' => ['user:{self}'],
|
||||
],
|
||||
$userId = $dbForInternal->getId();
|
||||
$invitee = $dbForInternal->createDocument('users', new Document([
|
||||
'$id' => $userId,
|
||||
'$read' => ['user:'.$userId, 'role:all'],
|
||||
'$write' => ['user:'.$userId],
|
||||
'email' => $email,
|
||||
'emailVerification' => false,
|
||||
'status' => Auth::USER_STATUS_UNACTIVATED,
|
||||
'status' => true,
|
||||
'password' => Auth::passwordHash(Auth::passwordGenerator()),
|
||||
/**
|
||||
* Set the password update time to 0 for users created using
|
||||
@@ -352,31 +339,20 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
'registration' => \time(),
|
||||
'reset' => false,
|
||||
'name' => $name,
|
||||
'prefs' => [],
|
||||
'sessions' => [],
|
||||
'tokens' => [],
|
||||
], ['email' => $email]);
|
||||
'memberships' => [],
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
]));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('Account already exists', 409);
|
||||
}
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
if (false === $invitee) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
}
|
||||
|
||||
$isOwner = false;
|
||||
|
||||
foreach ($memberships as $member) {
|
||||
if ($member->getAttribute('userId') == $invitee->getId()) {
|
||||
throw new Exception('User has already been invited or is already a member of this team', 409);
|
||||
}
|
||||
|
||||
if ($member->getAttribute('userId') == $user->getId() && \in_array('owner', $member->getAttribute('roles', []))) {
|
||||
$isOwner = true;
|
||||
}
|
||||
}
|
||||
$isOwner = Authorization::isRole('team:'.$team->getId().'/owner');;
|
||||
|
||||
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
|
||||
throw new Exception('User is not allowed to send invitations for this team', 401);
|
||||
@@ -385,11 +361,9 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$secret = Auth::tokenGenerator();
|
||||
|
||||
$membership = new Document([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'$permissions' => [
|
||||
'read' => ['*'],
|
||||
'write' => ['user:'.$invitee->getId(), 'team:'.$team->getId().'/owner'],
|
||||
],
|
||||
'$id' => $dbForInternal->getId(),
|
||||
'$read' => ['role:all'],
|
||||
'$write' => ['user:'.$invitee->getId(), 'team:'.$team->getId().'/owner'],
|
||||
'userId' => $invitee->getId(),
|
||||
'teamId' => $team->getId(),
|
||||
'roles' => $roles,
|
||||
@@ -401,32 +375,30 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
|
||||
if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership
|
||||
Authorization::disable();
|
||||
$membership = $projectDB->createDocument($membership->getArrayCopy());
|
||||
try {
|
||||
$membership = $dbForInternal->createDocument('memberships', $membership);
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('User has already been invited or is already a member of this team', 409);
|
||||
}
|
||||
|
||||
$team = $projectDB->updateDocument(\array_merge($team->getArrayCopy(), [
|
||||
'sum' => $team->getAttribute('sum', 0) + 1,
|
||||
]));
|
||||
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1));
|
||||
|
||||
// Attach user to team
|
||||
$invitee->setAttribute('memberships', $membership, Document::SET_TYPE_APPEND);
|
||||
|
||||
$invitee = $projectDB->updateDocument($invitee->getArrayCopy());
|
||||
|
||||
if (false === $invitee) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
$invitee = $dbForInternal->updateDocument('users', $invitee->getId(), $invitee);
|
||||
|
||||
Authorization::reset();
|
||||
} else {
|
||||
$membership = $projectDB->createDocument($membership->getArrayCopy());
|
||||
}
|
||||
|
||||
if (false === $membership) {
|
||||
throw new Exception('Failed saving membership to DB', 500);
|
||||
try {
|
||||
$membership = $dbForInternal->createDocument('memberships', $membership);
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception('User has already been invited or is already a member of this team', 409);
|
||||
}
|
||||
}
|
||||
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'teamId' => $team->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url = Template::unParseURL($url);
|
||||
|
||||
if (!$isPrivilegedUser && !$isAppUser) { // No need of confirmation when in admin or app mode
|
||||
@@ -448,16 +420,108 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$audits
|
||||
->setParam('userId', $invitee->getId())
|
||||
->setParam('event', 'teams.memberships.create')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
;
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic(new Document(\array_merge($membership->getArrayCopy(), [
|
||||
'email' => $email,
|
||||
'name' => $name,
|
||||
])), Response::MODEL_MEMBERSHIP)
|
||||
;
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($membership
|
||||
->setAttribute('email', $email)
|
||||
->setAttribute('name', $name)
|
||||
, Response::MODEL_MEMBERSHIP);
|
||||
});
|
||||
|
||||
App::get('/v1/teams/:teamId/memberships')
|
||||
->desc('Get Team Memberships')
|
||||
->groups(['api', 'teams'])
|
||||
->label('scope', 'teams.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
->label('sdk.method', 'getMemberships')
|
||||
->label('sdk.description', '/docs/references/teams/get-team-members.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP_LIST)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('cursor', '', new UID(), 'ID of the membership used as the starting point for the query, excluding the membership itself. Should be used for efficient pagination when working with large sets of data.', true)
|
||||
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
if (!empty($cursor)) {
|
||||
$cursorMembership = $dbForInternal->getDocument('memberships', $cursor);
|
||||
|
||||
if ($cursorMembership->isEmpty()) {
|
||||
throw new Exception("Membership '{$cursor}' for the 'cursor' value not found.", 400);
|
||||
}
|
||||
}
|
||||
|
||||
$memberships = $dbForInternal->find('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], $limit, $offset, [], [$orderType], $cursorMembership ?? null, $cursorDirection);
|
||||
$sum = $dbForInternal->count('memberships', [new Query('teamId', Query::TYPE_EQUAL, [$teamId])], APP_LIMIT_COUNT);
|
||||
$users = [];
|
||||
|
||||
foreach ($memberships as $membership) {
|
||||
if (empty($membership->getAttribute('userId', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp = $dbForInternal->getDocument('users', $membership->getAttribute('userId', null))->getArrayCopy(['email', 'name']);
|
||||
|
||||
$users[] = new Document(\array_merge($temp, $membership->getArrayCopy()));
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'memberships' => $users,
|
||||
'sum' => $sum,
|
||||
]), Response::MODEL_MEMBERSHIP_LIST);
|
||||
});
|
||||
|
||||
App::get('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->desc('Get Team Membership')
|
||||
->groups(['api', 'teams'])
|
||||
->label('scope', 'teams.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
->label('sdk.method', 'getMembership')
|
||||
->label('sdk.description', '/docs/references/teams/get-team-member.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP_LIST)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('membershipId', '', new UID(), 'membership unique ID.')
|
||||
->inject('response')
|
||||
->inject('dbForInternal')
|
||||
->action(function ($teamId, $membershipId, $response, $dbForInternal) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$membership = $dbForInternal->getDocument('memberships', $membershipId);
|
||||
|
||||
if($membership->isEmpty() || empty($membership->getAttribute('userId', null))) {
|
||||
throw new Exception('Membership not found', 404);
|
||||
}
|
||||
|
||||
$temp = $dbForInternal->getDocument('users', $membership->getAttribute('userId', null))->getArrayCopy(['email', 'name']);
|
||||
|
||||
$response->dynamic(new Document(\array_merge($temp, $membership->getArrayCopy())), Response::MODEL_MEMBERSHIP );
|
||||
});
|
||||
|
||||
App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
@@ -478,25 +542,29 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('audits')
|
||||
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $projectDB,$audits) {
|
||||
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForInternal, $audits) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$membership = $projectDB->getDocument($membershipId);
|
||||
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
|
||||
$membership = $dbForInternal->getDocument('memberships', $membershipId);
|
||||
if ($membership->isEmpty()) {
|
||||
throw new Exception('Membership not found', 404);
|
||||
}
|
||||
|
||||
$profile = $dbForInternal->getDocument('users', $membership->getAttribute('userId'));
|
||||
if ($profile->isEmpty()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::$roles);
|
||||
$isAppUser = Auth::isAppUser(Authorization::$roles);
|
||||
@@ -508,72 +576,17 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
|
||||
// Update the roles
|
||||
$membership->setAttribute('roles', $roles);
|
||||
$membership = $projectDB->updateDocument($membership->getArrayCopy());
|
||||
$membership = $dbForInternal->updateDocument('memberships', $membership->getId(), $membership);
|
||||
|
||||
if (false === $membership) {
|
||||
throw new Exception('Failed updating membership', 500);
|
||||
}
|
||||
// TODO sync updated membership in the user $profile object using TYPE_REPLACE
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'teams.memberships.update')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
;
|
||||
|
||||
$response->dynamic(new Document($membership->getArrayCopy()), Response::MODEL_MEMBERSHIP);
|
||||
});
|
||||
|
||||
App::get('/v1/teams/:teamId/memberships')
|
||||
->desc('Get Team Memberships')
|
||||
->groups(['api', 'teams'])
|
||||
->label('scope', 'teams.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
->label('sdk.method', 'getMemberships')
|
||||
->label('sdk.description', '/docs/references/teams/get-team-members.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_MEMBERSHIP_LIST)
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('limit', 25, new Range(0, 100), 'Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
|
||||
->param('offset', 0, new Range(0, 2000), 'Results offset. The default value is 0. Use this param to manage pagination.', true)
|
||||
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->action(function ($teamId, $search, $limit, $offset, $orderType, $response, $projectDB) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
$memberships = $projectDB->getCollection([
|
||||
'limit' => $limit,
|
||||
'offset' => $offset,
|
||||
'orderType' => $orderType,
|
||||
'search' => $search,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS,
|
||||
'teamId='.$teamId,
|
||||
],
|
||||
]);
|
||||
$users = [];
|
||||
|
||||
foreach ($memberships as $membership) {
|
||||
if (empty($membership->getAttribute('userId', null))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp = $projectDB->getDocument($membership->getAttribute('userId', null))->getArrayCopy(['email', 'name']);
|
||||
|
||||
$users[] = new Document(\array_merge($temp, $membership->getArrayCopy()));
|
||||
}
|
||||
|
||||
$response->dynamic(new Document(['sum' => $projectDB->getSum(), 'memberships' => $users]), Response::MODEL_MEMBERSHIP_LIST);
|
||||
$response->dynamic($membership, Response::MODEL_MEMBERSHIP);
|
||||
});
|
||||
|
||||
App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
@@ -595,22 +608,23 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('geodb')
|
||||
->inject('audits')
|
||||
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $projectDB, $geodb, $audits) {
|
||||
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForInternal, $geodb, $audits) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Document $user */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
|
||||
$protocol = $request->getProtocol();
|
||||
$membership = $projectDB->getDocument($membershipId);
|
||||
|
||||
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
|
||||
throw new Exception('Invite not found', 404);
|
||||
$membership = $dbForInternal->getDocument('memberships', $membershipId);
|
||||
|
||||
if ($membership->isEmpty()) {
|
||||
throw new Exception('Membership not found', 404);
|
||||
}
|
||||
|
||||
if ($membership->getAttribute('teamId') !== $teamId) {
|
||||
@@ -619,11 +633,11 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
@@ -635,14 +649,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
throw new Exception('Invite does not belong to current user ('.$user->getAttribute('email').')', 401);
|
||||
}
|
||||
|
||||
if (empty($user->getId())) {
|
||||
$user = $projectDB->getCollectionFirst([ // Get user
|
||||
'limit' => 1,
|
||||
'filters' => [
|
||||
'$collection='.Database::SYSTEM_COLLECTION_USERS,
|
||||
'$id='.$userId,
|
||||
],
|
||||
]);
|
||||
if ($user->isEmpty()) {
|
||||
$user = $dbForInternal->getDocument('users', $userId); // Get user
|
||||
}
|
||||
|
||||
if ($membership->getAttribute('userId') !== $user->getId()) {
|
||||
@@ -661,13 +669,14 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
|
||||
// Log user in
|
||||
|
||||
Authorization::setRole('user:'.$user->getId());
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$expiry = \time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$secret = Auth::tokenGenerator();
|
||||
$session = new Document(array_merge([
|
||||
'$collection' => Database::SYSTEM_COLLECTION_SESSIONS,
|
||||
'$permissions' => ['read' => ['user:'.$user->getId()], 'write' => ['user:'.$user->getId()]],
|
||||
'$id' => $dbForInternal->getId(),
|
||||
'userId' => $user->getId(),
|
||||
'provider' => Auth::SESSION_PROVIDER_EMAIL,
|
||||
'providerUid' => $user->getAttribute('email'),
|
||||
@@ -678,32 +687,28 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
|
||||
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
|
||||
|
||||
$session = $dbForInternal->createDocument('sessions', $session
|
||||
->setAttribute('$read', ['user:'.$user->getId()])
|
||||
->setAttribute('$write', ['user:'.$user->getId()])
|
||||
);
|
||||
|
||||
$user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND);
|
||||
|
||||
Authorization::setRole('user:'.$userId);
|
||||
|
||||
$user = $projectDB->updateDocument($user->getArrayCopy());
|
||||
|
||||
if (false === $user) {
|
||||
throw new Exception('Failed saving user to DB', 500);
|
||||
}
|
||||
$user = $dbForInternal->updateDocument('users', $user->getId(), $user);
|
||||
$membership = $dbForInternal->updateDocument('memberships', $membership->getId(), $membership);
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
$team = $projectDB->updateDocument(\array_merge($team->getArrayCopy(), [
|
||||
'sum' => $team->getAttribute('sum', 0) + 1,
|
||||
]));
|
||||
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('sum', $team->getAttribute('sum', 0) + 1));
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
if (false === $team) {
|
||||
throw new Exception('Failed saving team to DB', 500);
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'teams.memberships.update.status')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
;
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
@@ -717,10 +722,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
|
||||
;
|
||||
|
||||
$response->dynamic(new Document(\array_merge($membership->getArrayCopy(), [
|
||||
'email' => $user->getAttribute('email'),
|
||||
'name' => $user->getAttribute('name'),
|
||||
])), Response::MODEL_MEMBERSHIP);
|
||||
$response->dynamic($membership
|
||||
->setAttribute('email', $user->getAttribute('email'))
|
||||
->setAttribute('name', $user->getAttribute('name'))
|
||||
, Response::MODEL_MEMBERSHIP);
|
||||
});
|
||||
|
||||
App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
@@ -737,18 +742,18 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->param('teamId', '', new UID(), 'Team unique ID.')
|
||||
->param('membershipId', '', new UID(), 'Membership ID.')
|
||||
->inject('response')
|
||||
->inject('projectDB')
|
||||
->inject('dbForInternal')
|
||||
->inject('audits')
|
||||
->inject('events')
|
||||
->action(function ($teamId, $membershipId, $response, $projectDB, $audits, $events) {
|
||||
->action(function ($teamId, $membershipId, $response, $dbForInternal, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Database\Database $projectDB */
|
||||
/** @var Utopia\Database\Database $dbForInternal */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$membership = $projectDB->getDocument($membershipId);
|
||||
$membership = $dbForInternal->getDocument('memberships', $membershipId);
|
||||
|
||||
if (empty($membership->getId()) || Database::SYSTEM_COLLECTION_MEMBERSHIPS != $membership->getCollection()) {
|
||||
if ($membership->isEmpty()) {
|
||||
throw new Exception('Invite not found', 404);
|
||||
}
|
||||
|
||||
@@ -756,30 +761,47 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
throw new Exception('Team IDs don\'t match', 404);
|
||||
}
|
||||
|
||||
$team = $projectDB->getDocument($teamId);
|
||||
$user = $dbForInternal->getDocument('users', $membership->getAttribute('userId'));
|
||||
|
||||
if (empty($team->getId()) || Database::SYSTEM_COLLECTION_TEAMS != $team->getCollection()) {
|
||||
if ($user->isEmpty()) {
|
||||
throw new Exception('User not found', 404);
|
||||
}
|
||||
|
||||
$team = $dbForInternal->getDocument('teams', $teamId);
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception('Team not found', 404);
|
||||
}
|
||||
|
||||
if (!$projectDB->deleteDocument($membership->getId())) {
|
||||
if (!$dbForInternal->deleteDocument('memberships', $membership->getId())) {
|
||||
throw new Exception('Failed to remove membership from DB', 500);
|
||||
}
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
$team = $projectDB->updateDocument(\array_merge($team->getArrayCopy(), [
|
||||
'sum' => \max($team->getAttribute('sum', 0) - 1, 0), // Ensure that sum >= 0
|
||||
]));
|
||||
$memberships = $user->getAttribute('memberships', []);
|
||||
|
||||
foreach ($memberships as $key => $child) {
|
||||
/** @var Document $child */
|
||||
|
||||
if ($membershipId == $child->getId()) {
|
||||
unset($memberships[$key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (false === $team) {
|
||||
throw new Exception('Failed saving team to DB', 500);
|
||||
Authorization::disable();
|
||||
|
||||
$dbForInternal->updateDocument('users', $user->getId(), $user->setAttribute('memberships', $memberships));
|
||||
|
||||
Authorization::reset();
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
$team = $dbForInternal->updateDocument('teams', $team->getId(), $team->setAttribute('sum', \max($team->getAttribute('sum', 0) - 1, 0)));
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $membership->getAttribute('userId'))
|
||||
->setParam('event', 'teams.memberships.delete')
|
||||
->setParam('resource', 'teams/'.$teamId)
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
;
|
||||
|
||||
$events
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user