1
0
Fork 0
mirror of synced 2024-06-14 08:44:49 +12:00

Merge pull request #8127 from appwrite/chore-sync-main

Sync main into 1.5.x
This commit is contained in:
Steven Nguyen 2024-05-16 13:15:52 -07:00 committed by GitHub
commit d32eb73293
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
96 changed files with 413 additions and 116 deletions

View file

@ -0,0 +1,19 @@
name: Check dependencies
# Adapted from https://google.github.io/osv-scanner/github-action/#scan-on-pull-request
on:
pull_request:
branches: [main, 1.*.x]
merge_group:
branches: [main, 1.*.x]
permissions:
# Require writing security events to upload SARIF file to security tab
security-events: write
# Only need to read contents
contents: read
jobs:
scan-pr:
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v1.7.1"

23
.github/workflows/stale.yml vendored Normal file
View file

@ -0,0 +1,23 @@
name: Mark stale issues
on:
schedule:
- cron: "0 0 * * *" # Midnight Runtime
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "This issue has been labeled as a 'question', indicating that it requires additional information from the requestor. It has been inactive for 7 days. If no further activity occurs, this issue will be closed in 14 days."
stale-issue-label: "stale"
days-before-stale: 7
days-before-close: 14
remove-stale-when-updated: true
close-issue-message: "This issue has been closed due to inactivity. If you still require assistance, please provide the requested information."
close-issue-reason: "not_planned"
operations-per-run: 100
only-labels: "question"

View file

@ -301,6 +301,143 @@ This will allow the Appwrite community to sufficiently discuss the new feature v
This is also important for the Appwrite lead developers to be able to provide technical input and potentially a different emphasis regarding the feature design and architecture. Some bigger features might need to go through our [RFC process](https://github.com/appwrite/rfc).
## Adding New Usage Metrics
These are the current metrics we collect usage stats for:
| Metric | Description |
|--------|-------------------------------------------------|
| teams | Total number of teams per project |
| users | Total number of users per project|
| executions | Total number of executions per project |
| databases | Total number of databases per project |
| collections | Total number of collections per project |
| {databaseInternalId}.collections | Total number of collections per database|
| documents | Total number of documents per project |
| {databaseInternalId}.{collectionInternalId}.documents | Total number of documents per collection |
| buckets | Total number of buckets per project |
| files | Total number of files per project |
| {bucketInternalId}.files.storage | Sum of files.storage per bucket (in bytes) |
| functions | Total number of functions per project |
| deployments | Total number of deployments per project |
| builds | Total number of builds per project |
| {resourceType}.{resourceInternalId}.deployments | Total number of deployments per function |
| executions | Total number of executions per project |
| {functionInternalId}.executions | Total number of executions per function |
| files.storage | Sum of files storage per project (in bytes) |
| deployments.storage | Sum of deployments storage per project (in bytes) |
| {resourceType}.{resourceInternalId}.deployments.storage | Sum of deployments storage per function (in bytes) |
| builds.storage | Sum of builds storage per project (in bytes) |
| builds.compute | Sum of compute duration per project (in seconds) |
| {functionInternalId}.builds.storage | Sum of builds storage per function (in bytes) |
| {functionInternalId}.builds.compute | Sum of compute duration per function (in seconds) |
| network.requests | Total number of network requests per project |
| executions.compute | Sum of compute duration per project (in seconds) |
| network.inbound | Sum of network inbound traffic per project (in bytes)|
| network.outbound | Sum of network outbound traffic per project (in bytes)|
> Note: The curly brackets in the metric name represents a template and is replaced with a value when the metric is processed.
Metrics are collected within 3 scopes Daily, monthly, an infinity. Adding new usage metric in order to aggregate usage stats is very simple, but very much dependent on where do you want to collect
statistics ,via API or via background worker. For both cases you will need to add a `const` variable in `app/init.php` under the usage metrics list using the naming convention `METRIC_<RESOURCE_NAME>` as shown below.
```php
// Usage metrics
const METRIC_FUNCTIONS = 'functions';
const METRIC_DEPLOYMENTS = 'deployments';
const METRIC_DEPLOYMENTS_STORAGE = 'deployments.storage';
```
Next follow the appropriate steps below depending on whether you're adding the metric to the API or the worker.
**API**
In file `app/controllers/shared/api.php` On the database listener, add to an existing or create a new switch case. Add a call to the usage worker with your new metric const like so:
```php
case $document->getCollection() === 'teams':
$queueForUsage
->addMetric(METRIC_TEAMS, $value); // per project
break;
```
There are cases when you need to handle metric that has a parent entity, like buckets.
Files are linked to a parent bucket, you should verify you remove the files stats when you delete a bucket.
In that case you need also to handle children removal using addReduce() method call.
```php
case $document->getCollection() === 'buckets': //buckets
$queueForUsage
->addMetric(METRIC_BUCKETS, $value); // per project
if ($event === Database::EVENT_DOCUMENT_DELETE) {
$queueForUsage
->addReduce($document);
}
break;
```
In addition, you will also need to add some logic to the `reduce()` method of the Usage worker located in `/src/Appwrite/Platform/Workers/Usage.php`, like so:
```php
case $document->getCollection() === 'buckets':
$files = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES)));
$storage = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{bucketInternalId}', $document->getInternalId(), METRIC_BUCKET_ID_FILES_STORAGE)));
if (!empty($files['value'])) {
$metrics[] = [
'key' => METRIC_FILES,
'value' => ($files['value'] * -1),
];
}
if (!empty($storage['value'])) {
$metrics[] = [
'key' => METRIC_FILES_STORAGE,
'value' => ($storage['value'] * -1),
];
}
break;
```
**Background worker**
You need to inject the usage queue in the desired worker on the constructor method
```php
/**
* @throws Exception
*/
public function __construct()
{
$this
->desc('Functions worker')
->groups(['functions'])
->inject('message')
->inject('dbForProject')
->inject('queueForFunctions')
->inject('queueForEvents')
->inject('queueForUsage')
->inject('log')
->callback(fn (Message $message, Database $dbForProject, Func $queueForFunctions, Event $queueForEvents, Usage $queueForUsage, Log $log) => $this->action($message, $dbForProject, $queueForFunctions, $queueForEvents, $queueForUsage, $log));
}
```
and then trigger the queue with the new metric like so:
```php
$queueForUsage
->addMetric(METRIC_BUILDS, 1)
->addMetric(METRIC_BUILDS_STORAGE, $build->getAttribute('size', 0))
->addMetric(METRIC_BUILDS_COMPUTE, (int)$build->getAttribute('duration', 0) * 1000)
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS), 1)
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE), $build->getAttribute('size', 0))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE), (int)$build->getAttribute('duration', 0) * 1000)
->setProject($project)
->trigger();
```
## Build
To build a new version of the Appwrite server, all you need to do is run the build.sh file like this:

View file

@ -11,6 +11,7 @@
</p>
<!-- [![Build Status](https://img.shields.io/travis/com/appwrite/appwrite?style=flat-square)](https://travis-ci.com/appwrite/appwrite) -->
[![We're Hiring](https://img.shields.io/static/v1?label=We're&message=Hiring&color=blue&style=flat-square)](https://appwrite.io/company/careers)
[![Hacktoberfest](https://img.shields.io/static/v1?label=hacktoberfest&message=friendly&color=191120&style=flat-square)](https://hacktoberfest.appwrite.io)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord?r=Github)
@ -25,7 +26,7 @@
[**Appwrite 云公开测试版!立即注册!**](https://cloud.appwrite.io)
Appwrite是一个基于Docker的端到端开发者平台其容器化的微服务库可应用于网页端移动端以及后端。Appwrite 通过视觉化界面简化了从零开始编写 API 的繁琐过程,在保证软件安全的前提下为开发者创造了一个高效的开发环境。
Appwrite 是一个基于 Docker 的端到端开发者平台其容器化的微服务库可应用于网页端移动端以及后端。Appwrite 通过视觉化界面简化了从零开始编写 API 的繁琐过程,在保证软件安全的前提下为开发者创造了一个高效的开发环境。
Appwrite 可以提供给开发者用户验证,外部授权,用户数据读写检索,文件储存,图像处理,云函数计算,[等多种服务](https://appwrite.io/docs).
@ -93,7 +94,6 @@ docker run -it --rm `
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。
需要自定义容器构架,请查看我们的 Docker [环境变量](https://appwrite.io/docs/environment-variables) 文档。您还可以参考我们的 [docker-compose.yml](https://appwrite.io/install/compose) 和 [.env](https://appwrite.io/install/env) 文件手动设置环境。
### 从旧版本升级
@ -104,71 +104,73 @@ docker run -it --rm `
开始使用 Appwrite 只需要在控制台创建一个新项目,选择开发平台,然后抓取我们的开发套件。您可以从以下的教程中找到你喜欢的平台开始使用 Appwrite。
| 类别 | 技术 |
|---------------------|------|
| **Web 应用** | [Web 快速开始](/docs/quick-starts/web) |
| | [Next.js 快速开始](/docs/quick-starts/nextjs) |
| | [React 快速开始](/docs/quick-starts/react) |
| | [Vue.js 快速开始](/docs/quick-starts/vue) |
| | [Nuxt 快速开始](/docs/quick-starts/nuxt) |
| | [SvelteKit 快速开始](/docs/quick-starts/sveltekit) |
| | [Refine 快速开始](/docs/quick-starts/refine) |
| | [Angular 快速开始](/docs/quick-starts/angular) |
| **苹果于安卓应用** | [React Native 快速开始](/docs/quick-starts/react-native) |
| | [Flutter 快速开始](/docs/quick-starts/flutter) |
| | [Apple 快速开始](/docs/quick-starts/apple) |
| | [Android 快速开始](/docs/quick-starts/android) |
| **服务器** | [Node.js 快速开始](/docs/quick-starts/node) |
| | [Python 快速开始](/docs/quick-starts/python) |
| | [.NET 快速开始](/docs/quick-starts/dotnet) |
| | [Dart 快速开始](/docs/quick-starts/dart) |
| | [Ruby 快速开始](/docs/quick-starts/ruby) |
| | [Deno 快速开始](/docs/quick-starts/deno) |
| | [PHP 快速开始](/docs/quick-starts/php) |
| | [Kotlin 快速开始](/docs/quick-starts/kotlin) |
| | [Swift 快速开始](/docs/quick-starts/swift) |
| 类别 | 技术 |
| ------------------ | --------------------------------------------------------------------------- |
| **Web 应用** | [Web 快速开始](https://appwrite.io/docs/quick-starts/web) |
| | [Next.js 快速开始](https://appwrite.io/docs/quick-starts/nextjs) |
| | [React 快速开始](https://appwrite.io/docs/quick-starts/react) |
| | [Vue.js 快速开始](https://appwrite.io/docs/quick-starts/vue) |
| | [Nuxt 快速开始](https://appwrite.io/docs/quick-starts/nuxt) |
| | [SvelteKit 快速开始](https://appwrite.io/docs/quick-starts/sveltekit) |
| | [Refine 快速开始](https://appwrite.io/docs/quick-starts/refine) |
| | [Angular 快速开始](https://appwrite.io/docs/quick-starts/angular) |
| **苹果于安卓应用** | [React Native 快速开始](https://appwrite.io/docs/quick-starts/react-native) |
| | [Flutter 快速开始](https://appwrite.io/docs/quick-starts/flutter) |
| | [Apple 快速开始](https://appwrite.io/docs/quick-starts/apple) |
| | [Android 快速开始](https://appwrite.io/docs/quick-starts/android) |
| **服务器** | [Node.js 快速开始](https://appwrite.io/docs/quick-starts/node) |
| | [Python 快速开始](https://appwrite.io/docs/quick-starts/python) |
| | [.NET 快速开始](https://appwrite.io/docs/quick-starts/dotnet) |
| | [Dart 快速开始](https://appwrite.io/docs/quick-starts/dart) |
| | [Ruby 快速开始](https://appwrite.io/docs/quick-starts/ruby) |
| | [Deno 快速开始](https://appwrite.io/docs/quick-starts/deno) |
| | [PHP 快速开始](https://appwrite.io/docs/quick-starts/php) |
| | [Kotlin 快速开始](https://appwrite.io/docs/quick-starts/kotlin) |
| | [Swift 快速开始](https://appwrite.io/docs/quick-starts/swift) |
### 软件服务
* [**帐户**](https://appwrite.io/docs/references/cloud/client-web/account) -管理当前用户的帐户和登录方式。跟踪和管理用户 Session登录设备登录方法和查看相关记录。
* [**用户**](https://appwrite.io/docs/server/users) - 在以管理员模式登录时管理和列出所有用户。
* [**团队**](https://appwrite.io/docs/references/cloud/client-web/teams) - 管理用户分组。邀请成员,管理团队中的用户权限和用户角色。
* [**数据库**](https://appwrite.io/docs/references/cloud/client-web/databases) - 管理数据库文档和文档集。用检索界面来对文档和文档集进行读取,创建,更新,和删除。
* [**贮存**](https://appwrite.io/docs/references/cloud/client-web/storage) - 管理文件的阅读、创建、删除和预览。设置文件的预览来满足程序的个性化需求。所有文件都由 ClamAV 扫描并安全存储和加密。
* [**云函数**](https://appwrite.io/docs/server/functions) - 在安全隔离的环境中运行自定义代码。这些代码可以被事件CRON或者手动操作触发。
* [**消息传递**](https://appwrite.io/docs/references/cloud/client-web/messaging) - 使用 Appwrite 消息传递功能通过推送通知、电子邮件和短信与用户进行通信。
* [**语言适配**](https://appwrite.io/docs/references/cloud/client-web/locale) - 根据用户所在的的国家和地区做出合适的语言适配。
* [**头像**](https://appwrite.io/docs/references/cloud/client-web/avatars) -管理用户头像、国家旗帜、浏览器图标、信用卡符号,和生成二维码。
如需完整的 API 界面文档,请访问 [https://appwrite.io/docs](https://appwrite.io/docs)。如需更多教程、新闻和公告,请订阅我们的 [博客](https://medium.com/appwrite-io) 和 加入我们的[Discord 社区](https://discord.gg/GSeTUeA)。
- [**帐户**](https://appwrite.io/docs/references/cloud/client-web/account) -管理当前用户的帐户和登录方式。跟踪和管理用户 Session登录设备登录方法和查看相关记录。
- [**用户**](https://appwrite.io/docs/server/users) - 在以管理员模式登录时管理和列出所有用户。
- [**团队**](https://appwrite.io/docs/references/cloud/client-web/teams) - 管理用户分组。邀请成员,管理团队中的用户权限和用户角色。
- [**数据库**](https://appwrite.io/docs/references/cloud/client-web/databases) - 管理数据库文档和文档集。用检索界面来对文档和文档集进行读取,创建,更新,和删除。
- [**贮存**](https://appwrite.io/docs/references/cloud/client-web/storage) - 管理文件的阅读、创建、删除和预览。设置文件的预览来满足程序的个性化需求。所有文件都由 ClamAV 扫描并安全存储和加密。
- [**云函数**](https://appwrite.io/docs/server/functions) - 在安全隔离的环境中运行自定义代码。这些代码可以被事件CRON或者手动操作触发。
- [**消息传递**](https://appwrite.io/docs/references/cloud/client-web/messaging) - 使用 Appwrite 消息传递功能通过推送通知、电子邮件和短信与用户进行通信。
- [**语言适配**](https://appwrite.io/docs/references/cloud/client-web/locale) - 根据用户所在的的国家和地区做出合适的语言适配。
- [**头像**](https://appwrite.io/docs/references/cloud/client-web/avatars) -管理用户头像、国家旗帜、浏览器图标、信用卡符号,和生成二维码。
如需完整的 API 界面文档,请访问 [https://appwrite.io/docs](https://appwrite.io/docs)。如需更多教程、新闻和公告,请订阅我们的 [博客](https://medium.com/appwrite-io) 和 加入我们的[Discord 社区](https://discord.gg/GSeTUeA)。
### 开发套件
以下是当前支持的平台和语言列表。如果您想帮助我们为您选择的平台添加支持,您可以访问我们的 [SDK 生成器](https://github.com/appwrite/sdk-generator) 项目并查看我们的 [贡献指南](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md)。
#### 客户端
* ✅ &nbsp; [Web](https://github.com/appwrite/sdk-for-web) (由 Appwrite 团队维护)
* ✅ &nbsp; [Flutter](https://github.com/appwrite/sdk-for-flutter) (由 Appwrite 团队维护)
* ✅ &nbsp; [Apple](https://github.com/appwrite/sdk-for-apple) (由 Appwrite 团队维护)
* ✅ &nbsp; [Android](https://github.com/appwrite/sdk-for-android) (由 Appwrite 团队维护)
* ✅ &nbsp; [React Native](https://github.com/appwrite/sdk-for-react-native) - **公测** (由 Appwrite 团队维护)
- ✅ &nbsp; [Web](https://github.com/appwrite/sdk-for-web) (由 Appwrite 团队维护)
- ✅ &nbsp; [Flutter](https://github.com/appwrite/sdk-for-flutter) (由 Appwrite 团队维护)
- ✅ &nbsp; [Apple](https://github.com/appwrite/sdk-for-apple) (由 Appwrite 团队维护)
- ✅ &nbsp; [Android](https://github.com/appwrite/sdk-for-android) (由 Appwrite 团队维护)
- ✅ &nbsp; [React Native](https://github.com/appwrite/sdk-for-react-native) - **公测** (由 Appwrite 团队维护)
#### 服务器
* ✅ &nbsp; [NodeJS](https://github.com/appwrite/sdk-for-node) (由 Appwrite 团队维护)
* ✅ &nbsp; [PHP](https://github.com/appwrite/sdk-for-php) (由 Appwrite 团队维护)
* ✅ &nbsp; [Dart](https://github.com/appwrite/sdk-for-dart) (由 Appwrite 团队维护)
* ✅ &nbsp; [Deno](https://github.com/appwrite/sdk-for-deno) (由 Appwrite 团队维护)
* ✅ &nbsp; [Ruby](https://github.com/appwrite/sdk-for-ruby) (由 Appwrite 团队维护)
* ✅ &nbsp; [Python](https://github.com/appwrite/sdk-for-python) (由 Appwrite 团队维护)
* ✅ &nbsp; [Kotlin](https://github.com/appwrite/sdk-for-kotlin) (由 Appwrite 团队维护)
* ✅ &nbsp; [Swift](https://github.com/appwrite/sdk-for-swift) (由 Appwrite 团队维护)
* ✅ &nbsp; [.NET](https://github.com/appwrite/sdk-for-dotnet) - **公测** (由 Appwrite 团队维护)
- ✅ &nbsp; [NodeJS](https://github.com/appwrite/sdk-for-node) (由 Appwrite 团队维护)
- ✅ &nbsp; [PHP](https://github.com/appwrite/sdk-for-php) (由 Appwrite 团队维护)
- ✅ &nbsp; [Dart](https://github.com/appwrite/sdk-for-dart) (由 Appwrite 团队维护)
- ✅ &nbsp; [Deno](https://github.com/appwrite/sdk-for-deno) (由 Appwrite 团队维护)
- ✅ &nbsp; [Ruby](https://github.com/appwrite/sdk-for-ruby) (由 Appwrite 团队维护)
- ✅ &nbsp; [Python](https://github.com/appwrite/sdk-for-python) (由 Appwrite 团队维护)
- ✅ &nbsp; [Kotlin](https://github.com/appwrite/sdk-for-kotlin) (由 Appwrite 团队维护)
- ✅ &nbsp; [Swift](https://github.com/appwrite/sdk-for-swift) (由 Appwrite 团队维护)
- ✅ &nbsp; [.NET](https://github.com/appwrite/sdk-for-dotnet) - **公测** (由 Appwrite 团队维护)
#### 开发者社区
* ✅ &nbsp; [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (维护者 [Michael Gangolf](https://github.com/m1ga/))
* ✅ &nbsp; [Godot Engine](https://github.com/GodotNuts/appwrite-sdk) (维护者 [fenix-hub @GodotNuts](https://github.com/fenix-hub))
找不到需要的的 SDK - 欢迎通过发起PR来帮助我们完善Appwrite的软件生态环境 [SDK 生成器](https://github.com/appwrite/sdk-generator)!
- ✅ &nbsp; [Appcelerator Titanium](https://github.com/m1ga/ti.appwrite) (维护者 [Michael Gangolf](https://github.com/m1ga/))
- ✅ &nbsp; [Godot Engine](https://github.com/GodotNuts/appwrite-sdk) (维护者 [fenix-hub @GodotNuts](https://github.com/fenix-hub))
找不到需要的的 SDK - 欢迎通过发起 PR 来帮助我们完善 Appwrite 的软件生态环境 [SDK 生成器](https://github.com/appwrite/sdk-generator)!
## 软件架构
@ -180,13 +182,13 @@ Appwrite API 界面层利用后台缓存和任务委派来提供极速的响应
## 贡献代码
为了确保正确审查,所有代码贡献 - 包括来自具有直接提交更改权限的贡献者 - 都必须提交PR请求并在合并分支之前得到核心开发人员的批准。
为了确保正确审查,所有代码贡献 - 包括来自具有直接提交更改权限的贡献者 - 都必须提交 PR 请求并在合并分支之前得到核心开发人员的批准。
我们欢迎所有人提交PR如果您愿意提供帮助可以在 [贡献指南](CONTRIBUTING.md) 中了解有关如何为项目做出贡献的更多信息。
我们欢迎所有人提交 PR如果您愿意提供帮助可以在 [贡献指南](CONTRIBUTING.md) 中了解有关如何为项目做出贡献的更多信息。
## 安全
为了保护您的隐私请避免在GitHub 上发布安全问题。发送问题至 security@appwrite.io我们将为您做更细致的解答。
为了保护您的隐私,请避免在 GitHub 上发布安全问题。发送问题至 security@appwrite.io我们将为您做更细致的解答。
## 订阅我们

View file

@ -10,7 +10,6 @@
<br />
</p>
<!-- [![Build Status](https://img.shields.io/travis/com/appwrite/appwrite?style=flat-square)](https://travis-ci.com/appwrite/appwrite) -->
[![We're Hiring](https://img.shields.io/static/v1?label=We're&message=Hiring&color=blue&style=flat-square)](https://appwrite.io/company/careers)
@ -142,29 +141,29 @@ Choose from one of the providers below:
Getting started with Appwrite is as easy as creating a new project, choosing your platform, and integrating its SDK into your code. You can easily get started with your platform of choice by reading one of our Getting Started tutorials.
| Platform | Technology |
|--------------------|------------|
| **Web app** | [Quick start for Web](/docs/quick-starts/web) |
| | [Quick start for Next.js](/docs/quick-starts/nextjs) |
| | [Quick start for React](/docs/quick-starts/react) |
| | [Quick start for Vue.js](/docs/quick-starts/vue) |
| | [Quick start for Nuxt](/docs/quick-starts/nuxt) |
| | [Quick start for SvelteKit](/docs/quick-starts/sveltekit) |
| | [Quick start for Refine](/docs/quick-starts/refine) |
| | [Quick start for Angular](/docs/quick-starts/angular) |
| **Mobile and Native** | [Quick start for React Native](/docs/quick-starts/react-native) |
| | [Quick start for Flutter](/docs/quick-starts/flutter) |
| | [Quick start for Apple](/docs/quick-starts/apple) |
| | [Quick start for Android](/docs/quick-starts/android) |
| **Server** | [Quick start for Node.js](/docs/quick-starts/node) |
| | [Quick start for Python](/docs/quick-starts/python) |
| | [Quick start for .NET](/docs/quick-starts/dotnet) |
| | [Quick start for Dart](/docs/quick-starts/dart) |
| | [Quick start for Ruby](/docs/quick-starts/ruby) |
| | [Quick start for Deno](/docs/quick-starts/deno) |
| | [Quick start for PHP](/docs/quick-starts/php) |
| | [Quick start for Kotlin](/docs/quick-starts/kotlin) |
| | [Quick start for Swift](/docs/quick-starts/swift) |
| Platform | Technology |
| --------------------- | ---------------------------------------------------------------------------------- |
| **Web app** | [Quick start for Web](https://appwrite.io/docs/quick-starts/web) |
| | [Quick start for Next.js](https://appwrite.io/docs/quick-starts/nextjs) |
| | [Quick start for React](https://appwrite.io/docs/quick-starts/react) |
| | [Quick start for Vue.js](https://appwrite.io/docs/quick-starts/vue) |
| | [Quick start for Nuxt](https://appwrite.io/docs/quick-starts/nuxt) |
| | [Quick start for SvelteKit](https://appwrite.io/docs/quick-starts/sveltekit) |
| | [Quick start for Refine](https://appwrite.io/docs/quick-starts/refine) |
| | [Quick start for Angular](https://appwrite.io/docs/quick-starts/angular) |
| **Mobile and Native** | [Quick start for React Native](https://appwrite.io/docs/quick-starts/react-native) |
| | [Quick start for Flutter](https://appwrite.io/docs/quick-starts/flutter) |
| | [Quick start for Apple](https://appwrite.io/docs/quick-starts/apple) |
| | [Quick start for Android](https://appwrite.io/docs/quick-starts/android) |
| **Server** | [Quick start for Node.js](https://appwrite.io/docs/quick-starts/node) |
| | [Quick start for Python](https://appwrite.io/docs/quick-starts/python) |
| | [Quick start for .NET](https://appwrite.io/docs/quick-starts/dotnet) |
| | [Quick start for Dart](https://appwrite.io/docs/quick-starts/dart) |
| | [Quick start for Ruby](https://appwrite.io/docs/quick-starts/ruby) |
| | [Quick start for Deno](https://appwrite.io/docs/quick-starts/deno) |
| | [Quick start for PHP](https://appwrite.io/docs/quick-starts/php) |
| | [Quick start for Kotlin](https://appwrite.io/docs/quick-starts/kotlin) |
| | [Quick start for Swift](https://appwrite.io/docs/quick-starts/swift) |
### Products

View file

@ -4,7 +4,7 @@ return [
'amex' => ['name' => 'American Express', 'path' => __DIR__ . '/credit-cards/amex.png'],
'argencard' => ['name' => 'Argencard', 'path' => __DIR__ . '/credit-cards/argencard.png'],
'cabal' => ['name' => 'Cabal', 'path' => __DIR__ . '/credit-cards/cabal.png'],
'censosud' => ['name' => 'Consosud', 'path' => __DIR__ . '/credit-cards/consosud.png'],
'cencosud' => ['name' => 'Cencosud', 'path' => __DIR__ . '/credit-cards/cencosud.png'],
'diners' => ['name' => 'Diners Club', 'path' => __DIR__ . '/credit-cards/diners.png'],
'discover' => ['name' => 'Discover', 'path' => __DIR__ . '/credit-cards/discover.png'],
'elo' => ['name' => 'Elo', 'path' => __DIR__ . '/credit-cards/elo.png'],

View file

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -11,7 +11,7 @@ return [
/** General Errors */
Exception::GENERAL_UNKNOWN => [
'name' => Exception::GENERAL_UNKNOWN,
'description' => 'An unknown error has occured. Please check the logs for more information.',
'description' => 'An unknown error has occurred. Please check the logs for more information.',
'code' => 500,
],
Exception::GENERAL_MOCK => [
@ -284,7 +284,7 @@ return [
],
Exception::USER_CHALLENGE_REQUIRED => [
'name' => Exception::USER_CHALLENGE_REQUIRED,
'description' => 'A recently succeessful challenge is required to complete this action. A challenge is considered recent for 5 minutes.',
'description' => 'A recently successful challenge is required to complete this action. A challenge is considered recent for 5 minutes.',
'code' => 401,
],
Exception::USER_OAUTH2_BAD_REQUEST => [
@ -489,7 +489,7 @@ return [
],
Exception::REPOSITORY_NOT_FOUND => [
'name' => Exception::REPOSITORY_NOT_FOUND,
'description' => 'Repository with the requested ID could not be found. Check to see if the ID is correct, or create the respository.',
'description' => 'Repository with the requested ID could not be found. Check to see if the ID is correct, or create the repository.',
'code' => 404,
],
Exception::PROVIDER_CONTRIBUTION_CONFLICT => [
@ -499,7 +499,7 @@ return [
],
Exception::GENERAL_PROVIDER_FAILURE => [
'name' => Exception::GENERAL_PROVIDER_FAILURE,
'description' => 'VCS (Version Control System) provider failed to proccess the request. We believe this is an error with the VCS provider. Try again, or contact support for more information.',
'description' => 'VCS (Version Control System) provider failed to process the request. We believe this is an error with the VCS provider. Try again, or contact support for more information.',
'code' => 400,
],

View file

@ -1,5 +1,13 @@
<?php
/**
* ISO 3166 standard country codes
* https://www.iso.org/iso-3166-country-codes.html
*
* Source:
* https://www.iso.org/obp/ui/#search/code/
*/
return [
'AF',
'AO',
@ -137,6 +145,7 @@ return [
'NZ',
'OM',
'PK',
'PS',
'PA',
'PE',
'PH',

View file

@ -136,6 +136,7 @@ return [
'NZ' => '64',
'OM' => '968',
'PK' => '92',
'PS' => '970',
'PA' => '507',
'PE' => '51',
'PH' => '63',

View file

@ -163,6 +163,7 @@
"countries.nz": "Nieu-Seeland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestine",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippyne",

View file

@ -163,6 +163,7 @@
"countries.nz": "نيوزيلندا",
"countries.om": "عمان",
"countries.pk": "باكستان",
"countries.ps": "فلسطين",
"countries.pa": "بنما",
"countries.pe": "بيرو",
"countries.ph": "الفلبين",

View file

@ -163,6 +163,7 @@
"countries.nz": "নিউজিলেণ্ড",
"countries.om": "ওমান",
"countries.pk": "পাকিস্তান",
"countries.ps": "প্যালেস্টাইন",
"countries.pa": "পানামা",
"countries.pe": "পেৰু",
"countries.ph": "ফিলিপাইনচ",

View file

@ -163,6 +163,7 @@
"countries.nz": "Yeni Zelandiya",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Fələstin",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippin",

View file

@ -163,6 +163,7 @@
"countries.nz": "Новая Зеландыя",
"countries.om": "Аман",
"countries.pk": "Пакістан",
"countries.ps": "Палестина",
"countries.pa": "Панама",
"countries.pe": "Перу",
"countries.ph": "Філіпіны",

View file

@ -163,6 +163,7 @@
"countries.nz": "Нова Зеландия",
"countries.om": "Оман",
"countries.pk": "Пакистан",
"countries.ps": "Палестина",
"countries.pa": "Панама",
"countries.pe": "Перу",
"countries.ph": "Филипини",

View file

@ -163,6 +163,7 @@
"countries.nz": "न्यूजीलैंड",
"countries.om": "ओमान",
"countries.pk": "पाकिस्तान",
"countries.ps": "पैलिस्टाइन",
"countries.pa": "पनामा",
"countries.pe": "पेरू",
"countries.ph": "फिलीपींस",

View file

@ -163,6 +163,7 @@
"countries.nz": "নিউজিল্যান্ড",
"countries.om": "ওমান",
"countries.pk": "পাকিস্তান",
"countries.ps": "প্যালেস্টাইন",
"countries.pa": "পানামা",
"countries.pe": "পেরু",
"countries.ph": "ফিলিপাইন",

View file

@ -163,6 +163,7 @@
"countries.nz": "Novi Zeland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipini",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nova Zelanda",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panamà",
"countries.pe": "Perú",
"countries.ph": "Filipines",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nový Zéland",
"countries.om": "Omán",
"countries.pk": "Pákistán",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipíny",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palæstina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippinerne",

View file

@ -163,6 +163,7 @@
"countries.nz": "Neuseeland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palästina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippinen",

View file

@ -163,6 +163,7 @@
"countries.nz": "Νέα Ζηλανδία",
"countries.om": "Ομάν",
"countries.pk": "Πακιστάν",
"countries.ps": "Παλαιστίνη",
"countries.pa": "Παναμάς",
"countries.pe": "Περού",
"countries.ph": "Φιλιππίνες",

View file

@ -180,6 +180,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestine",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippines",

View file

@ -162,6 +162,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestinio",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippines",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nueva Zelanda",
"countries.om": "Omán",
"countries.pk": "Pakistán",
"countries.ps": "Palestina",
"countries.pa": "Panamá",
"countries.pe": "Perú",
"countries.ph": "Filipinas",

View file

@ -163,6 +163,7 @@
"countries.nz": "نیوزلند",
"countries.om": "عمان",
"countries.pk": "پاکستان",
"countries.ps": "فلسطین",
"countries.pa": "پاناما",
"countries.pe": "پرو",
"countries.ph": "فیلیپین",

View file

@ -163,6 +163,7 @@
"countries.nz": "Uusi-Seelanti",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestiina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippiinit",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nýsæland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipsoyggjar",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nouvelle-Zélande",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestine",
"countries.pa": "Panama",
"countries.pe": "Pérou",
"countries.ph": "Philippines",

View file

@ -163,6 +163,7 @@
"countries.nz": "An Nua-Shéalainn",
"countries.om": "Óman",
"countries.pk": "An Phacastáin",
"countries.ps": "An Phalaistín",
"countries.pa": "Panama",
"countries.pe": "Peiriú",
"countries.ph": "Na hOileáin Fhilipíneacha",

View file

@ -163,6 +163,7 @@
"countries.nz": "ન્યુઝીલેન્ડ",
"countries.om": "ઓમાન",
"countries.pk": "પાકિસ્તાન",
"countries.ps": "પેલેસ્ટાઇન",
"countries.pa": "પનામા",
"countries.pe": "પેરુ",
"countries.ph": "ફિલિપાઇન્સ",

View file

@ -163,6 +163,7 @@
"countries.nz": "ניו זילנד",
"countries.om": "עומאן",
"countries.pk": "פקיסטן",
"countries.ps": "פלסטין",
"countries.pa": "פנמה",
"countries.pe": "פרו",
"countries.ph": "הפיליפינים",

View file

@ -163,6 +163,7 @@
"countries.nz": "न्यूजीलैंड",
"countries.om": "ओमान",
"countries.pk": "पाकिस्तान",
"countries.ps": "पैलिस्टाइन",
"countries.pa": "पनामा",
"countries.pe": "पेरू",
"countries.ph": "फिलीपींस",

View file

@ -163,6 +163,7 @@
"countries.nz": "Novi Zeland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipini",

View file

@ -163,6 +163,7 @@
"countries.nz": "Új-Zéland",
"countries.om": "Omán",
"countries.pk": "Pakisztán",
"countries.ps": "Palesztina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Fülöp-szigetek",

View file

@ -163,6 +163,7 @@
"countries.nz": "Նոր Զելանդիա",
"countries.om": "Օման",
"countries.pk": "Պակիստան",
"countries.ps": "Պաղեստին",
"countries.pa": "Պանամա",
"countries.pe": "Պերու",
"countries.ph": "Ֆիլիպիններ",

View file

@ -163,6 +163,7 @@
"countries.nz": "Selandia Baru",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipina",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nýja Sjáland",
"countries.om": "Óman",
"countries.pk": "Pakistan",
"countries.ps": "Palestína",
"countries.pa": "Panama",
"countries.pe": "Perú",
"countries.ph": "Filippseyjar",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nuova Zelanda",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Perù",
"countries.ph": "Filippine",

View file

@ -163,6 +163,7 @@
"countries.nz": "ニュージーランド",
"countries.om": "オマーン",
"countries.pk": "パキスタン",
"countries.ps": "パレスチナ",
"countries.pa": "パナマ",
"countries.pe": "ペルー",
"countries.ph": "フィリピン",

View file

@ -163,6 +163,7 @@
"countries.nz": "Selandia Anyar",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipina",

View file

@ -163,6 +163,7 @@
"countries.nz": "នូវែលសេឡង់",
"countries.om": "អូម៉ង់",
"countries.pk": "ប៉ាគីស្ថាន",
"countries.ps": "ប៉ាលេស្ទីន",
"countries.pa": "ប៉ាណាម៉ា",
"countries.pe": "ប៉េរូ",
"countries.ph": "ហ្វីលីពីន",

View file

@ -163,6 +163,7 @@
"countries.nz": "ನ್ಯೂಜಿಲ್ಯಾಂಡ್",
"countries.om": "ಓಮನ್",
"countries.pk": "ಪಾಕಿಸ್ತಾನ",
"countries.ps": "ಪ್ಯಾಲೇಸ್ಟೈನ್",
"countries.pa": "ಪನಾಮ",
"countries.pe": "ಪೆರು",
"countries.ph": "ಫಿಲಿಪೈನ್ಸ್",

View file

@ -163,6 +163,7 @@
"countries.nz": "뉴질랜드",
"countries.om": "오만",
"countries.pk": "파키스탄",
"countries.ps": "팔레스타인",
"countries.pa": "파나마",
"countries.pe": "페루",
"countries.ph": "필리핀 제도",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippines",

View file

@ -163,6 +163,7 @@
"countries.nz": "Neiséiland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippinnen",

View file

@ -163,6 +163,7 @@
"countries.nz": "Naujoji Zelandija",
"countries.om": "Omanas",
"countries.pk": "Pakistanas",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipinai",

View file

@ -163,6 +163,7 @@
"countries.nz": "Jaunzēlande",
"countries.om": "Omāna",
"countries.pk": "Pakistāna",
"countries.ps": "Palestīna",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipīnas",

View file

@ -163,6 +163,7 @@
"countries.nz": "ന്യൂസിലൻഡ്",
"countries.om": "ഒമാൻ",
"countries.pk": "പാക്കിസ്ഥാൻ",
"countries.ps": "പാലസ്തീൻ",
"countries.pa": "പനാമ",
"countries.pe": "പെറു",
"countries.ph": "ഫിലിപ്പീൻസ്",

View file

@ -163,6 +163,7 @@
"countries.nz": "न्यूजीलैंड",
"countries.om": "ओमान",
"countries.pk": "पाकिस्तान",
"countries.ps": "पॅलेस्टाईन",
"countries.pa": "पनामा",
"countries.pe": "पेरू",
"countries.ph": "फिलीपींस",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestin",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipina",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippinene",

View file

@ -163,6 +163,7 @@
"countries.nz": "न्युजिल्याण्ड",
"countries.om": "ओमान",
"countries.pk": "पाकिस्तान",
"countries.ps": "प्यालेस्टाइन",
"countries.pa": "पनामा",
"countries.pe": "पेरू",
"countries.ph": "फिलिपिन्स",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nieuw Zeeland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippijnen",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippinene",

View file

@ -163,6 +163,7 @@
"countries.nz": "ନିଉଜିଲାଣ୍ଡ୍",
"countries.om": "ଓମାନ",
"countries.pk": "ପାକିସ୍ତାନ",
"countries.ps": "ପାଲେସ୍ତାଇନ",
"countries.pa": "ପାନାମା",
"countries.pe": "ପେରୁ",
"countries.ph": "ଫିଲିପାଇନ୍ସ",

View file

@ -163,6 +163,7 @@
"countries.nz": "ਨਿਊਜ਼ੀਲੈਂਡ",
"countries.om": "ਓਮਾਨ",
"countries.pk": "ਪਾਕਿਸਤਾਨ",
"countries.ps": "ਫਿਲਿਸਤੀਨ",
"countries.pa": "ਪਨਾਮਾ",
"countries.pe": "ਪੇਰੂ",
"countries.ph": "ਫਿਲਪੀਨਜ਼",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nowa Zelandia",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestyna",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipiny",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nova Zelândia",
"countries.om": "Omã",
"countries.pk": "Paquistão",
"countries.ps": "Palestina",
"countries.pa": "Panamá",
"countries.pe": "Peru",
"countries.ph": "Filipinas",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nova Zelândia",
"countries.om": "Omã",
"countries.pk": "Paquistão",
"countries.ps": "Palestina",
"countries.pa": "Panamá",
"countries.pe": "Peru",
"countries.ph": "Filipinas",

View file

@ -163,6 +163,7 @@
"countries.nz": "Noua Zeelandă",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippines",

View file

@ -163,6 +163,7 @@
"countries.nz": "Новая Зеландия",
"countries.om": "Оман",
"countries.pk": "Пакистан",
"countries.ps": "Палестина",
"countries.pa": "Панама",
"countries.pe": "Перу",
"countries.ph": "Филлиппины",

View file

@ -163,6 +163,7 @@
"countries.nz": "न्यूजीलैंड",
"countries.om": "ओमान",
"countries.pk": "पाकिस्तान",
"countries.ps": "पैलिस्टाइन",
"countries.pa": "पनामा",
"countries.pe": "पेरू",
"countries.ph": "फिलीपींस",

View file

@ -163,6 +163,7 @@
"countries.nz": "نيو زيلينڊ",
"countries.om": "عمان",
"countries.pk": "پاڪستان",
"countries.ps": "فلسطين",
"countries.pa": "پاناما",
"countries.pe": "پيرو",
"countries.ph": "فلپائن",

View file

@ -163,6 +163,7 @@
"countries.nz": "නිව්සීලන්තය",
"countries.om": "ඕමානය",
"countries.pk": "පාකිස්තානය",
"countries.ps": "පලස්තීනය",
"countries.pa": "පැනමාව",
"countries.pe": "පේරු",
"countries.ph": "පිලිපීනය",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nový Zéland",
"countries.om": "Omán",
"countries.pk": "Pakistan",
"countries.ps": "Palestína",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipíny",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nova Zelandija",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipini",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakisitani",
"countries.ps": "Palestine",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippines",

View file

@ -163,6 +163,7 @@
"countries.nz": "Zelanda e Re",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestinë",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipine",

View file

@ -163,6 +163,7 @@
"countries.nz": "Nya Zeeland",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filippinerna",

View file

@ -163,6 +163,7 @@
"countries.nz": "நியூசிலாந்து",
"countries.om": "ஓமான்",
"countries.pk": "பாகிஸ்தான்",
"countries.ps": "பாலஸ்தீன்",
"countries.pa": "பனாமா",
"countries.pe": "பெரு",
"countries.ph": "பிலிப்பைன்ஸ்",

View file

@ -163,6 +163,7 @@
"countries.nz": "న్యూజిలాండ్",
"countries.om": "ఒమన్",
"countries.pk": "పాకిస్తాన్",
"countries.ps": "పాలస్తీన్",
"countries.pa": "పనామా",
"countries.pe": "పెరూ",
"countries.ph": "ఫిలిప్పీన్స్",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "โอมาน",
"countries.pk": "ปากีสถาน",
"countries.ps": "ปาเลสไตน์",
"countries.pa": "ปานามา",
"countries.pe": "เปรู",
"countries.ph": "ฟิลิปปินส์",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestina",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Pilipinas",

View file

@ -163,6 +163,7 @@
"countries.nz": "Yeni Zelanda",
"countries.om": "Umman",
"countries.pk": "Pakistan",
"countries.ps": "Filistin",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Filipinler",

View file

@ -163,6 +163,7 @@
"countries.nz": "Нова Зеландія",
"countries.om": "Оман",
"countries.pk": "Пакістан",
"countries.ps": "Палестина",
"countries.pa": "Панама",
"countries.pe": "Перу",
"countries.ph": "Філіппіни",

View file

@ -163,6 +163,7 @@
"countries.nz": "نیوزی لینڈ",
"countries.om": "عمان",
"countries.pk": "پاکستان",
"countries.ps": "فلسطین",
"countries.pa": "پانامہ",
"countries.pe": "پیرو",
"countries.ph": "فلپائن",

View file

@ -163,6 +163,7 @@
"countries.nz": "New Zealand",
"countries.om": "Oman",
"countries.pk": "Pakistan",
"countries.ps": "Palestine",
"countries.pa": "Panama",
"countries.pe": "Peru",
"countries.ph": "Philippines",

View file

@ -163,6 +163,7 @@
"countries.nz": "新西兰",
"countries.om": "阿曼",
"countries.pk": "巴基斯坦",
"countries.ps": "巴勒斯坦",
"countries.pa": "巴拿马",
"countries.pe": "秘鲁",
"countries.ph": "菲律宾",

View file

@ -163,6 +163,7 @@
"countries.nz": "紐西蘭",
"countries.om": "阿曼",
"countries.pk": "巴基斯坦",
"countries.ps": "巴勒斯坦",
"countries.pa": "巴拿馬",
"countries.pe": "秘魯",
"countries.ph": "菲律賓",

View file

@ -123,7 +123,8 @@ $createSession = function (string $userId, string $secret, Request $request, Res
Authorization::skip(fn () => $dbForProject->deleteDocument('tokens', $verifiedToken->getId()));
$dbForProject->purgeCachedDocument('users', $user->getId());
if ($verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_MAGIC_URL) {
// Magic URL + Email OTP
if ($verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_MAGIC_URL || $verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_EMAIL) {
$user->setAttribute('emailVerification', true);
}

View file

@ -1282,7 +1282,7 @@ App::get('/v1/functions/:functionId/deployments')
}
// Set resource queries
$queries[] = Query::equal('resourceId', [$function->getId()]);
$queries[] = Query::equal('resourceInternalId', [$function->getInternalId()]);
$queries[] = Query::equal('resourceType', ['functions']);
/**

View file

@ -49,6 +49,12 @@ App::post('/v1/proxy/rules')
if ($domain === $mainDomain) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your main domain to specific resource. Please use subdomain or a different domain.');
}
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
if (str_ends_with($domain, $functionsDomain)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your functions domain or it\'s subdomain to specific resource. Please use different domain.');
}
if ($domain === 'localhost' || $domain === APP_HOSTNAME_INTERNAL) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please pick another one.');
}

View file

@ -697,7 +697,7 @@ App::shutdown()
if ($project->getId() !== 'console') {
if ($mode !== APP_MODE_ADMIN) {
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
$fileSize = 0;
$file = $request->getFiles('file');
if (!empty($file)) {

View file

@ -837,7 +837,7 @@ $register->set('pools', function () {
/**
* Get Resource
*
* Creation could be reused accross connection types like database, cache, queue, etc.
* Creation could be reused across connection types like database, cache, queue, etc.
*
* Resource assignment to an adapter will happen below.
*/
@ -847,7 +847,7 @@ $register->set('pools', function () {
$resource = function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) {
return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) {
return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnDatabase};charset=utf8mb4", $dsnUser, $dsnPass, array(
// No need to set PDO::ATTR_ERRMODE it is overwitten in PDOProxy
// No need to set PDO::ATTR_ERRMODE it is overwritten in PDOProxy
PDO::ATTR_TIMEOUT => 3, // Seconds
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,

View file

@ -103,7 +103,7 @@ class CalcTierStats extends Action
return;
} catch (\Throwable $th) {
Console::error("Unexpected error occured with Project ID {$projectId}");
Console::error("Unexpected error occurred with Project ID {$projectId}");
Console::error('[Error] Type: ' . get_class($th));
Console::error('[Error] Message: ' . $th->getMessage());
Console::error('[Error] File: ' . $th->getFile());
@ -129,7 +129,7 @@ class CalcTierStats extends Action
$data = $this->getData($project, $dbForConsole, $dbForProject);
$csv->insertOne($data);
} catch (\Throwable $th) {
Console::error("Unexpected error occured with Project ID {$projectId}");
Console::error("Unexpected error occurred with Project ID {$projectId}");
Console::error('[Error] Type: ' . get_class($th));
Console::error('[Error] Message: ' . $th->getMessage());
Console::error('[Error] File: ' . $th->getFile());

View file

@ -50,7 +50,7 @@ class CreateInfMetric extends Action
$dbForProject = call_user_func($getProjectDB, $project);
$this->getUsageData($dbForProject, $project);
} catch (\Throwable $th) {
Console::error("Unexpected error occured with Project ID {$projectId}");
Console::error("Unexpected error occurred with Project ID {$projectId}");
Console::error('[Error] Type: ' . get_class($th));
Console::error('[Error] Message: ' . $th->getMessage());
Console::error('[Error] File: ' . $th->getFile());
@ -72,7 +72,7 @@ class CreateInfMetric extends Action
$dbForProject = call_user_func($getProjectDB, $project);
$this->getUsageData($dbForProject, $project);
} catch (\Throwable $th) {
Console::error("Unexpected error occured with Project ID {$projectId}");
Console::error("Unexpected error occurred with Project ID {$projectId}");
Console::error('[Error] Type: ' . get_class($th));
Console::error('[Error] Message: ' . $th->getMessage());
Console::error('[Error] File: ' . $th->getFile());

View file

@ -109,7 +109,7 @@ class Doctor extends Action
Console::log('🟢 Logging adapter is enabled (' . $providerName . ')');
}
\sleep(0.2);
\usleep(200 * 1000); // Sleep for 0.2 seconds
try {
Console::log("\n" . '[Connectivity]');
@ -194,7 +194,7 @@ class Doctor extends Action
Console::error('🔴 ' . str_pad("SMTP", 47, '.') . 'disconnected');
}
\sleep(0.2);
\usleep(200 * 1000); // Sleep for 0.2 seconds
Console::log('');
Console::log('[Volumes]');
@ -222,7 +222,7 @@ class Doctor extends Action
}
}
\sleep(0.2);
\usleep(200 * 1000); // Sleep for 0.2 seconds
Console::log('');
Console::log('[Disk Space]');

View file

@ -42,7 +42,7 @@ class PatchRecreateRepositoriesDocuments extends Action
$dbForProject = call_user_func($getProjectDB, $project);
$this->recreateRepositories($dbForConsole, $dbForProject, $project);
} catch (\Throwable $th) {
Console::error("Unexpected error occured with Project ID {$projectId}");
Console::error("Unexpected error occurred with Project ID {$projectId}");
Console::error('[Error] Type: ' . get_class($th));
Console::error('[Error] Message: ' . $th->getMessage());
Console::error('[Error] File: ' . $th->getFile());
@ -64,7 +64,7 @@ class PatchRecreateRepositoriesDocuments extends Action
$dbForProject = call_user_func($getProjectDB, $project);
$this->recreateRepositories($dbForConsole, $dbForProject, $project);
} catch (\Throwable $th) {
Console::error("Unexpected error occured with Project ID {$projectId}");
Console::error("Unexpected error occurred with Project ID {$projectId}");
Console::error('[Error] Type: ' . get_class($th));
Console::error('[Error] Message: ' . $th->getMessage());
Console::error('[Error] File: ' . $th->getFile());

View file

@ -202,6 +202,8 @@ trait AccountBase
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals($userId, $response['body']['$id']);
$this->assertEquals($userId, $response['body']['$id']);
$this->assertTrue($response['body']['emailVerification']);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/token', array_merge([
'origin' => 'http://localhost',

View file

@ -33,7 +33,7 @@ class BatchTest extends Scope
$this->assertArrayNotHasKey('errors', $response['body'][1]);
$this->assertArrayHasKey('localeListCountries', $response['body'][0]['data']);
$this->assertArrayHasKey('localeListContinents', $response['body'][1]['data']);
$this->assertEquals(196, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(7, $response['body'][1]['data']['localeListContinents']['total']);
}
@ -56,8 +56,8 @@ class BatchTest extends Scope
$this->assertArrayNotHasKey('errors', $response['body'][1]);
$this->assertArrayHasKey('localeListCountries', $response['body'][0]['data']);
$this->assertArrayHasKey('localeListCountries', $response['body'][1]['data']);
$this->assertEquals(196, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(196, $response['body'][1]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][1]['data']['localeListCountries']['total']);
}
public function testArrayBatchedMutations()
@ -184,7 +184,7 @@ class BatchTest extends Scope
$this->assertArrayHasKey('localeListCountries', $response['body'][0]['data']);
$this->assertArrayHasKey('localeListContinents', $response['body'][1]['data']);
$this->assertArrayHasKey('accountCreate', $response['body'][2]['data']);
$this->assertEquals(196, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(7, $response['body'][1]['data']['localeListContinents']['total']);
$this->assertEquals('Tester 1', $response['body'][2]['data']['accountCreate']['name']);
}
@ -225,8 +225,8 @@ class BatchTest extends Scope
$this->assertArrayHasKey('localeListCountries', $response['body'][0]['data']);
$this->assertArrayHasKey('localeListCountries', $response['body'][1]['data']);
$this->assertArrayHasKey('accountCreate', $response['body'][2]['data']);
$this->assertEquals(196, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(196, $response['body'][1]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][1]['data']['localeListCountries']['total']);
$this->assertArrayHasKey('_id', $response['body'][2]['data']['accountCreate']);
}
@ -251,7 +251,7 @@ class BatchTest extends Scope
$this->assertArrayNotHasKey('errors', $response['body']);
$this->assertArrayHasKey('localeListCountries', $response['body']['data']);
$this->assertArrayHasKey('localeListContinents', $response['body']['data']);
$this->assertEquals(196, $response['body']['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body']['data']['localeListCountries']['total']);
$this->assertEquals(7, $response['body']['data']['localeListContinents']['total']);
}
@ -275,7 +275,7 @@ class BatchTest extends Scope
$this->assertIsArray($response['body']['data']);
$this->assertArrayNotHasKey('errors', $response['body']);
$this->assertArrayHasKey('localeListCountries', $response['body']['data']);
$this->assertEquals(196, $response['body']['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body']['data']['localeListCountries']['total']);
}
public function testQueryBatchedMutations()

View file

@ -30,7 +30,7 @@ class ContentTypeTest extends Scope
$this->assertIsArray($response['body']['data']);
$this->assertArrayNotHasKey('errors', $response['body']);
$response = $response['body']['data']['localeListCountries'];
$this->assertEquals(196, $response['total']);
$this->assertEquals(197, $response['total']);
}
public function testSingleQueryJSONContentType()
@ -46,7 +46,7 @@ class ContentTypeTest extends Scope
$this->assertIsArray($response['body']['data']);
$this->assertArrayNotHasKey('errors', $response['body']);
$response = $response['body']['data']['localeListCountries'];
$this->assertEquals(196, $response['total']);
$this->assertEquals(197, $response['total']);
}
public function testArrayBatchedJSONContentType()
@ -69,7 +69,7 @@ class ContentTypeTest extends Scope
$this->assertArrayNotHasKey('errors', $response['body'][1]);
$this->assertArrayHasKey('localeListCountries', $response['body'][0]['data']);
$this->assertArrayHasKey('localeListContinents', $response['body'][1]['data']);
$this->assertEquals(196, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body'][0]['data']['localeListCountries']['total']);
$this->assertEquals(7, $response['body'][1]['data']['localeListContinents']['total']);
}
@ -94,7 +94,7 @@ class ContentTypeTest extends Scope
$this->assertArrayNotHasKey('errors', $response['body']);
$this->assertArrayHasKey('localeListCountries', $response['body']['data']);
$this->assertArrayHasKey('localeListContinents', $response['body']['data']);
$this->assertEquals(196, $response['body']['data']['localeListCountries']['total']);
$this->assertEquals(197, $response['body']['data']['localeListCountries']['total']);
$this->assertEquals(7, $response['body']['data']['localeListContinents']['total']);
}

View file

@ -45,7 +45,7 @@ trait LocaleBase
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertEquals(196, $response['body']['total']);
$this->assertEquals(197, $response['body']['total']);
$this->assertEquals($response['body']['countries'][0]['name'], 'Afghanistan');
$this->assertEquals($response['body']['countries'][0]['code'], 'AF');
@ -59,7 +59,7 @@ trait LocaleBase
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertEquals(196, $response['body']['total']);
$this->assertEquals(197, $response['body']['total']);
$this->assertEquals($response['body']['countries'][0]['name'], 'Afganistán');
$this->assertEquals($response['body']['countries'][0]['code'], 'AF');
@ -120,7 +120,7 @@ trait LocaleBase
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertEquals(195, $response['body']['total']);
$this->assertEquals(196, $response['body']['total']);
$this->assertIsArray($response['body']['phones']);
$this->assertEquals($response['body']['phones'][0]['code'], '+1');
$this->assertEquals($response['body']['phones'][0]['countryName'], 'Canada');
@ -247,7 +247,7 @@ trait LocaleBase
}
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertEquals(196, $response['body']['total']);
$this->assertEquals(197, $response['body']['total']);
$response = $this->client->call(Client::METHOD_GET, '/locale/continents', [
'content-type' => 'application/json',

View file

@ -2,17 +2,43 @@
namespace Tests\E2E\Services\Projects;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideServer;
use Utopia\System\System;
class ProjectsCustomServerTest extends Scope
{
use ProjectCustom;
use SideServer;
public function testMock()
// Domains
public function testCreateProjectRule()
{
$this->assertEquals(true, true);
$headers = array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-mode' => 'admin',
'cookie' => 'a_session_console=' . $this->getRoot()['session'],
]);
$response = $this->client->call(Client::METHOD_POST, '/proxy/rules', $headers, [
'resourceType' => 'api',
'domain' => 'api.appwrite.test',
]);
$this->assertEquals(201, $response['headers']['status-code']);
// prevent functions domain
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
$response = $this->client->call(Client::METHOD_POST, '/proxy/rules', $headers, [
'resourceType' => 'api',
'domain' => $functionsDomain,
]);
$this->assertEquals(400, $response['headers']['status-code']);
}
}