Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
834872870f | ||
|
|
1946fca9f6 | ||
|
|
6af57ca48e | ||
|
|
3c8e4da34d | ||
|
|
3b1f2afbd5 | ||
|
|
34ab21730d | ||
|
|
70fbf69c56 | ||
|
|
62be0e1d00 | ||
|
|
2c55f5aaa6 | ||
|
|
681b6031aa | ||
|
|
ab03b4e3ca | ||
|
|
583a18dcd7 | ||
|
|
3b9318c2fc | ||
|
|
e836df13ba | ||
|
|
023597842e | ||
|
|
c57ec57277 | ||
|
|
6978f6960e | ||
|
|
95ba881ab7 | ||
|
|
708b6279e0 | ||
|
|
0295dfcc63 | ||
|
|
06f138b39d | ||
|
|
524ce8789f | ||
|
|
8db247c840 | ||
|
|
b11749c452 | ||
|
|
c38a5177dd | ||
|
|
abae54f72c | ||
|
|
bf2b3b68e3 | ||
|
|
11d2b06b67 | ||
|
|
fe94717196 | ||
|
|
81b3e81d83 | ||
|
|
9fd8c5ab9d | ||
|
|
871e4b70f7 | ||
|
|
3e7cf6d60a | ||
|
|
bd18edc197 | ||
|
|
0f182817ec | ||
|
|
c323c227f9 | ||
|
|
d72ba2a4b9 | ||
|
|
ccb96d6525 | ||
|
|
2dcebf3083 | ||
|
|
cb85cfc5d9 | ||
|
|
4aaa07d57b | ||
|
|
d07b543e71 | ||
|
|
08b74007f7 | ||
|
|
813424aa3c | ||
|
|
e28333ed63 | ||
|
|
172ebb5f7f | ||
|
|
0f5480cbc0 | ||
|
|
e34fc92c7c | ||
|
|
bb01c9e9e9 | ||
|
|
ec6683cfa9 | ||
|
|
c2d0aded6d | ||
|
|
9345025ade | ||
|
|
31ca35782b | ||
|
|
2505e25da8 | ||
|
|
88d6150db2 | ||
|
|
faed019d92 | ||
|
|
b318c2cc08 | ||
|
|
eb4340cf4c | ||
|
|
ee09e2c91b | ||
|
|
e6e7c5c816 | ||
|
|
e9841e53b9 | ||
|
|
7d86ce76d8 | ||
|
|
e75441a097 | ||
|
|
ffb86ace38 | ||
|
|
aab8bca91e | ||
|
|
963760678c | ||
|
|
70e27748be | ||
|
|
556e00b62b | ||
|
|
e95aeed56c | ||
|
|
362520ff4a | ||
|
|
1299fffdb2 | ||
|
|
7cade1a27d | ||
|
|
20d90e06f2 | ||
|
|
ef163e8517 | ||
|
|
a0d4e4736c | ||
|
|
3f1c4c2095 | ||
|
|
370a8e231c | ||
|
|
83bcad6e17 | ||
|
|
aa5ea7f3a1 | ||
|
|
8a77eaf2bb | ||
|
|
fe308b4f1f | ||
|
|
e43a3109eb | ||
|
|
d9fbe9658d | ||
|
|
1e2f5bcb84 | ||
|
|
088d0998cd | ||
|
|
a7165e6a32 | ||
|
|
fd4b43569b | ||
|
|
b4536a94e0 | ||
|
|
e5261e7d70 | ||
|
|
60912cb084 | ||
|
|
7149deeacb | ||
|
|
59f613f9bb | ||
|
|
8184bc8c78 | ||
|
|
6c193f4862 | ||
|
|
23b245e058 | ||
|
|
ae5267cda7 | ||
|
|
f1b5807174 | ||
|
|
6e77221da0 | ||
|
|
4de935a322 | ||
|
|
86b66d70bf | ||
|
|
828b9349c3 | ||
|
|
9cb860d446 | ||
|
|
313a6b0f7e | ||
|
|
6eff011100 | ||
|
|
04140c2acc | ||
|
|
0f961f0d04 | ||
|
|
25f7741d3c | ||
|
|
2ff339dad4 | ||
|
|
91dd4c9c6f | ||
|
|
8413909b12 | ||
|
|
a4d4b6ffb5 | ||
|
|
cbdd344490 | ||
|
|
8fd877810d | ||
|
|
04711d8c02 | ||
|
|
5a5d43f3d0 | ||
|
|
3e462ded0a | ||
|
|
de96b2511a | ||
|
|
90899b92e3 | ||
|
|
4eece99768 | ||
|
|
971a4b8f30 | ||
|
|
418185b914 | ||
|
|
167011ce87 | ||
|
|
3d69a35d5a | ||
|
|
aac90ea8b8 | ||
|
|
56aa503146 | ||
|
|
875a60fe07 | ||
|
|
3427755695 | ||
|
|
68238193d2 | ||
|
|
07926534bf | ||
|
|
a2a0a1405f | ||
|
|
195edd19ac | ||
|
|
6cf333141c | ||
|
|
12dbb1d50d | ||
|
|
9dff192508 | ||
|
|
650627bfb4 | ||
|
|
4016895b8f | ||
|
|
3b7aea22c2 | ||
|
|
50fe0bf98d | ||
|
|
4f0a7de868 | ||
|
|
1933e48d9c | ||
|
|
90228a5ffb | ||
|
|
063c2be38f | ||
|
|
ff9845c9b9 | ||
|
|
bd5bfc04ef | ||
|
|
7a131d3508 | ||
|
|
d77dbebe8b | ||
|
|
8eadaec676 | ||
|
|
c55030387f | ||
|
|
5f2512dc4f | ||
|
|
f6fc425c98 | ||
|
|
810d650aba | ||
|
|
817a3808e5 | ||
|
|
d96910138f | ||
|
|
b8673ac07f | ||
|
|
246c8ce939 | ||
|
|
49d89a4206 | ||
|
|
ba45c191c5 | ||
|
|
74f9464c18 | ||
|
|
c5dfabdb7c | ||
|
|
bfdd2b65dc | ||
|
|
2c803b262c | ||
|
|
9bc793b216 | ||
|
|
fcf15689e8 | ||
|
|
aef38aa114 | ||
|
|
d81f2f8b5c | ||
|
|
e119bf6777 | ||
|
|
7402145c9d | ||
|
|
74f4ebf90e | ||
|
|
d6e53d8e2e | ||
|
|
e3f59c696d | ||
|
|
107a185953 | ||
|
|
f6b5deda6d | ||
|
|
d9fc6b70ad | ||
|
|
a0605b14cb | ||
|
|
6c652ba3ae | ||
|
|
2a5b3317bf | ||
|
|
19ad2088a0 | ||
|
|
6ad34a7bf7 | ||
|
|
57c7ebb53d | ||
|
|
ad56782b49 | ||
|
|
ce5a04a37d | ||
|
|
e8fb2f8ae1 | ||
|
|
697c30f559 | ||
|
|
34d587d7c5 | ||
|
|
0547dbc454 | ||
|
|
a3324b7453 | ||
|
|
df017bccb2 | ||
|
|
c4ab6f5aff | ||
|
|
891c1c4093 | ||
|
|
507c8bd3ec | ||
|
|
2de4e71662 | ||
|
|
8508e6009b | ||
|
|
a39341ada8 | ||
|
|
c451074278 | ||
|
|
cce6222184 | ||
|
|
6e09bcf6c6 |
@@ -0,0 +1,7 @@
|
||||
reviews:
|
||||
auto_review:
|
||||
base_branches:
|
||||
- main
|
||||
- 1.6.x
|
||||
- 1.7.x
|
||||
- feat-sites # temporary until merged to 1.7.x
|
||||
@@ -82,7 +82,6 @@ _APP_EXECUTOR_SECRET=your-secret-key
|
||||
_APP_EXECUTOR_HOST=http://exc1/v1
|
||||
_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1
|
||||
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29
|
||||
_APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,flutter,other,react,vue,analog,angular,vite
|
||||
_APP_MAINTENANCE_INTERVAL=86400
|
||||
_APP_MAINTENANCE_DELAY=
|
||||
_APP_MAINTENANCE_RETENTION_CACHE=2592000
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
|
||||
@@ -122,6 +122,14 @@ jobs:
|
||||
docker load --input /tmp/${{ env.IMAGE }}.tar
|
||||
docker compose up -d
|
||||
sleep 10
|
||||
|
||||
- name: Wait for Open Runtimes
|
||||
timeout-minutes: 3
|
||||
run: |
|
||||
while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do
|
||||
echo "Waiting for Executor to come online"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
- name: Run General Tests
|
||||
run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/General --debug
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Appwrite Init has concluded! You can check out all the latest announcements [on our Init website](https://appwrite.io/init) :rocket:
|
||||
> [Get started with Appwrite](https://apwr.dev/appcloud)
|
||||
|
||||
<br />
|
||||
<p align="center">
|
||||
@@ -24,11 +24,9 @@
|
||||
|
||||
English | [简体中文](README-CN.md)
|
||||
|
||||
[**Announcing Appwrite Cloud Public Beta! Sign up today!**](https://cloud.appwrite.io)
|
||||
|
||||
Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker<nobr> microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.
|
||||
|
||||
Using Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, and [more services](https://appwrite.io/docs).
|
||||
Using Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, messaging, and [more services](https://appwrite.io/docs).
|
||||
|
||||
<p align="center">
|
||||
<br />
|
||||
@@ -52,7 +50,7 @@ Table of Contents:
|
||||
- [Upgrade from an Older Version](#upgrade-from-an-older-version)
|
||||
- [One-Click Setups](#one-click-setups)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Services](#services)
|
||||
- [Products](#products)
|
||||
- [SDKs](#sdks)
|
||||
- [Client](#client)
|
||||
- [Server](#server)
|
||||
|
||||
@@ -25,7 +25,7 @@ use Utopia\Queue\Publisher;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\System\System;
|
||||
|
||||
// overwriting runtimes to be architectur agnostic for CLI
|
||||
// overwriting runtimes to be architecture agnostic for CLI
|
||||
Config::setParam('runtimes', (new Runtimes('v5'))->getAll(supported: false));
|
||||
|
||||
// require controllers after overwriting runtimes
|
||||
@@ -43,8 +43,7 @@ CLI::setResource('cache', function ($pools) {
|
||||
$adapters[] = $pools
|
||||
->get($value)
|
||||
->pop()
|
||||
->getResource()
|
||||
;
|
||||
->getResource();
|
||||
}
|
||||
|
||||
return new Cache(new Sharding($adapters));
|
||||
@@ -187,7 +186,7 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS)
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_TASK)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
// set tenant
|
||||
|
||||
@@ -1155,6 +1155,28 @@ return [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('owner'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => '', // "Appwrite" or empty string
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('region'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
@@ -1241,6 +1263,20 @@ return [
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_owner'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['owner'],
|
||||
'lengths' => [16],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_region'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['region'],
|
||||
'lengths' => [16],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
||||
@@ -579,6 +579,61 @@ return [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('deploymentCreatedAt'),
|
||||
'type' => Database::VAR_DATETIME,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => false,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => ['datetime'],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentId'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentInternalId'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentCreatedAt'),
|
||||
'type' => Database::VAR_DATETIME,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => false,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => ['datetime'],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentStatus'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => '',
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('vars'),
|
||||
'type' => Database::VAR_STRING,
|
||||
@@ -916,16 +971,16 @@ return [
|
||||
'default' => false,
|
||||
'array' => false,
|
||||
],
|
||||
// [
|
||||
// '$id' => ID::custom('logging'),
|
||||
// 'type' => Database::VAR_BOOLEAN,
|
||||
// 'signed' => true,
|
||||
// 'size' => 0,
|
||||
// 'format' => '',
|
||||
// 'filters' => [],
|
||||
// 'required' => true,
|
||||
// 'array' => false,
|
||||
// ],
|
||||
[
|
||||
'$id' => ID::custom('logging'),
|
||||
'type' => Database::VAR_BOOLEAN,
|
||||
'signed' => true,
|
||||
'size' => 0,
|
||||
'format' => '',
|
||||
'filters' => [],
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('framework'),
|
||||
'type' => Database::VAR_STRING,
|
||||
@@ -1003,6 +1058,83 @@ return [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('deploymentCreatedAt'),
|
||||
'type' => Database::VAR_DATETIME,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => false,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => ['datetime'],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('deploymentScreenshotLight'), // File ID from 'screenshots' Console bucket
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 32,
|
||||
'signed' => false,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('deploymentScreenshotDark'), // File ID from 'screenshots' Console bucket
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 32,
|
||||
'signed' => false,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentId'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentInternalId'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentCreatedAt'),
|
||||
'type' => Database::VAR_DATETIME,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => false,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => ['datetime'],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('latestDeploymentStatus'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => '',
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('vars'),
|
||||
'type' => Database::VAR_STRING,
|
||||
@@ -1550,6 +1682,17 @@ return [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('totalSize'),
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('status'),
|
||||
'type' => Database::VAR_STRING,
|
||||
@@ -1582,6 +1725,28 @@ return [
|
||||
'default' => '',
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('adapter'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 128,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => '',
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('fallbackFile'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
]
|
||||
],
|
||||
'indexes' => [
|
||||
@@ -1620,6 +1785,13 @@ return [
|
||||
'lengths' => [],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_totalSize'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['totalSize'],
|
||||
'lengths' => [],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_buildDuration'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
|
||||
@@ -27,6 +27,7 @@ $console = [
|
||||
'hostname' => 'localhost',
|
||||
], // Current host is added on app init
|
||||
],
|
||||
'region' => 'fra',
|
||||
'legalName' => '',
|
||||
'legalCountry' => '',
|
||||
'legalState' => '',
|
||||
|
||||
@@ -553,11 +553,6 @@ return [
|
||||
'description' => 'Site with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::SITE_FRAMEWORK_UNSUPPORTED => [
|
||||
'name' => Exception::SITE_FRAMEWORK_UNSUPPORTED,
|
||||
'description' => 'The requested framework is either inactive or unsupported. Please check the value of the _APP_SITES_FRAMEWORKS environment variable.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::SITE_TEMPLATE_NOT_FOUND => [
|
||||
'name' => Exception::SITE_TEMPLATE_NOT_FOUND,
|
||||
'description' => 'Site Template with the requested ID could not be found.',
|
||||
@@ -585,6 +580,11 @@ return [
|
||||
'description' => 'Build with the requested ID is already completed and cannot be canceled.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::BUILD_FAILED => [
|
||||
'name' => Exception::BUILD_FAILED,
|
||||
'description' => 'Build with the requested ID failed. Please check the logs for more information.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Deployments */
|
||||
Exception::DEPLOYMENT_NOT_FOUND => [
|
||||
|
||||
@@ -19,9 +19,10 @@ return [
|
||||
'analog' => [
|
||||
'key' => 'analog',
|
||||
'name' => 'Analog',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/analog/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/analog/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/analog/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -29,14 +30,14 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist/analog',
|
||||
'startCommand' => 'sh helpers/analog/server.sh',
|
||||
'startCommand' => 'bash helpers/analog/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist/analog/public',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
'fallbackFile' => 'index.html'
|
||||
]
|
||||
]
|
||||
@@ -44,9 +45,10 @@ return [
|
||||
'angular' => [
|
||||
'key' => 'angular',
|
||||
'name' => 'Angular',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/angular/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/angular/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/angular/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -54,14 +56,14 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist/angular',
|
||||
'startCommand' => 'sh helpers/angular/server.sh',
|
||||
'startCommand' => 'bash helpers/angular/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist/angular/browser',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
'fallbackFile' => 'index.csr.html'
|
||||
]
|
||||
]
|
||||
@@ -69,9 +71,10 @@ return [
|
||||
'nextjs' => [
|
||||
'key' => 'nextjs',
|
||||
'name' => 'Next.js',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/next-js/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/next-js/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/next-js/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -79,20 +82,21 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './.next',
|
||||
'startCommand' => 'sh helpers/next-js/server.sh',
|
||||
'startCommand' => 'bash helpers/next-js/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './out',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
]
|
||||
]
|
||||
],
|
||||
'react' => [
|
||||
'key' => 'react',
|
||||
'name' => 'React',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'adapters' => [
|
||||
@@ -101,7 +105,7 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
'fallbackFile' => 'index.html'
|
||||
]
|
||||
]
|
||||
@@ -109,9 +113,10 @@ return [
|
||||
'nuxt' => [
|
||||
'key' => 'nuxt',
|
||||
'name' => 'Nuxt',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/nuxt/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/nuxt/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/nuxt/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -119,20 +124,21 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './.output',
|
||||
'startCommand' => 'sh helpers/nuxt/server.sh',
|
||||
'startCommand' => 'bash helpers/nuxt/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run generate',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './output/public',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
]
|
||||
]
|
||||
],
|
||||
'vue' => [
|
||||
'key' => 'vue',
|
||||
'name' => 'Vue.js',
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'adapters' => [
|
||||
@@ -141,7 +147,7 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
'fallbackFile' => 'index.html'
|
||||
]
|
||||
]
|
||||
@@ -149,9 +155,10 @@ return [
|
||||
'sveltekit' => [
|
||||
'key' => 'sveltekit',
|
||||
'name' => 'SvelteKit',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/sveltekit/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/sveltekit/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/sveltekit/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -159,23 +166,24 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './build',
|
||||
'startCommand' => 'sh helpers/sveltekit/server.sh',
|
||||
'startCommand' => 'bash helpers/sveltekit/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './build',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
]
|
||||
]
|
||||
],
|
||||
'astro' => [
|
||||
'key' => 'astro',
|
||||
'name' => 'Astro',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/astro/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/astro/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/astro/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -183,23 +191,24 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'sh helpers/astro/server.sh',
|
||||
'startCommand' => 'bash helpers/astro/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
]
|
||||
]
|
||||
],
|
||||
'remix' => [
|
||||
'key' => 'remix',
|
||||
'name' => 'Remix',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'bundleCommand' => 'sh /usr/local/server/helpers/remix/bundle.sh',
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/remix/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/remix/env.sh',
|
||||
'adapters' => [
|
||||
'ssr' => [
|
||||
@@ -207,20 +216,21 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './build',
|
||||
'startCommand' => 'sh helpers/remix/server.sh',
|
||||
'startCommand' => 'bash helpers/remix/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './build/client',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
]
|
||||
]
|
||||
],
|
||||
'flutter' => [
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'flutter-3.29',
|
||||
'runtimes' => getVersions($templateRuntimes['FLUTTER']['versions'], 'flutter'),
|
||||
'adapters' => [
|
||||
@@ -229,13 +239,14 @@ return [
|
||||
'buildCommand' => 'flutter build web',
|
||||
'installCommand' => '',
|
||||
'outputDirectory' => './build/web',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
],
|
||||
],
|
||||
],
|
||||
'vite' => [
|
||||
'key' => 'vite',
|
||||
'name' => 'Vite',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'adapters' => [
|
||||
@@ -244,13 +255,14 @@ return [
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
],
|
||||
]
|
||||
],
|
||||
'other' => [
|
||||
'key' => 'other',
|
||||
'name' => 'Other',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'adapters' => [
|
||||
@@ -259,7 +271,7 @@ return [
|
||||
'buildCommand' => '',
|
||||
'installCommand' => '',
|
||||
'outputDirectory' => './',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
],
|
||||
]
|
||||
],
|
||||
|
||||
@@ -1,11 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Continent codes with names and approximate central coordinates
|
||||
*
|
||||
* Coordinates represent approximate geographical centers of each continent
|
||||
* Note: These are simplified centroids and may not represent the exact geographical center
|
||||
*/
|
||||
|
||||
return [
|
||||
'AF',
|
||||
'AN',
|
||||
'AS',
|
||||
'EU',
|
||||
'NA',
|
||||
'OC',
|
||||
'SA',
|
||||
'AF' => [
|
||||
'name' => 'Africa',
|
||||
'latitude' => 8.7832,
|
||||
'longitude' => 34.5085
|
||||
],
|
||||
'AN' => [
|
||||
'name' => 'Antarctica',
|
||||
'latitude' => -82.8628,
|
||||
'longitude' => 135.0000
|
||||
],
|
||||
'AS' => [
|
||||
'name' => 'Asia',
|
||||
'latitude' => 34.0479,
|
||||
'longitude' => 100.6197
|
||||
],
|
||||
'EU' => [
|
||||
'name' => 'Europe',
|
||||
'latitude' => 54.5260,
|
||||
'longitude' => 15.2551
|
||||
],
|
||||
'NA' => [
|
||||
'name' => 'North America',
|
||||
'latitude' => 54.5260,
|
||||
'longitude' => -105.2551
|
||||
],
|
||||
'OC' => [
|
||||
'name' => 'Oceania',
|
||||
'latitude' => -22.7359,
|
||||
'longitude' => 140.0188
|
||||
],
|
||||
'SA' => [
|
||||
'name' => 'South America',
|
||||
'latitude' => -8.7832,
|
||||
'longitude' => -55.4915
|
||||
],
|
||||
];
|
||||
|
||||
@@ -1,209 +1,210 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ISO 3166 standard country codes
|
||||
* ISO 3166 standard country codes with country names and coordinates
|
||||
* https://www.iso.org/iso-3166-country-codes.html
|
||||
*
|
||||
* Source:
|
||||
* https://www.iso.org/obp/ui/#search/code/
|
||||
* Coordinates source: Natural Earth Data (approximate country centroids)
|
||||
*/
|
||||
|
||||
return [
|
||||
'AF',
|
||||
'AO',
|
||||
'AL',
|
||||
'AD',
|
||||
'AE',
|
||||
'AR',
|
||||
'AM',
|
||||
'AG',
|
||||
'AU',
|
||||
'AT',
|
||||
'AZ',
|
||||
'BI',
|
||||
'BE',
|
||||
'BJ',
|
||||
'BF',
|
||||
'BD',
|
||||
'BG',
|
||||
'BH',
|
||||
'BS',
|
||||
'BA',
|
||||
'BY',
|
||||
'BZ',
|
||||
'BO',
|
||||
'BR',
|
||||
'BB',
|
||||
'BN',
|
||||
'BT',
|
||||
'BW',
|
||||
'CF',
|
||||
'CA',
|
||||
'CH',
|
||||
'CL',
|
||||
'CN',
|
||||
'CI',
|
||||
'CM',
|
||||
'CD',
|
||||
'CG',
|
||||
'CO',
|
||||
'KM',
|
||||
'CV',
|
||||
'CR',
|
||||
'CU',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DE',
|
||||
'DJ',
|
||||
'DM',
|
||||
'DK',
|
||||
'DO',
|
||||
'DZ',
|
||||
'EC',
|
||||
'EG',
|
||||
'ER',
|
||||
'ES',
|
||||
'EE',
|
||||
'ET',
|
||||
'FI',
|
||||
'FJ',
|
||||
'FR',
|
||||
'FM',
|
||||
'GA',
|
||||
'GB',
|
||||
'GE',
|
||||
'GH',
|
||||
'GN',
|
||||
'GM',
|
||||
'GW',
|
||||
'GQ',
|
||||
'GR',
|
||||
'GD',
|
||||
'GT',
|
||||
'GY',
|
||||
'HK',
|
||||
'HN',
|
||||
'HR',
|
||||
'HT',
|
||||
'HU',
|
||||
'ID',
|
||||
'IN',
|
||||
'IE',
|
||||
'IR',
|
||||
'IQ',
|
||||
'IS',
|
||||
'IL',
|
||||
'IT',
|
||||
'JM',
|
||||
'JO',
|
||||
'JP',
|
||||
'KZ',
|
||||
'KE',
|
||||
'KG',
|
||||
'KH',
|
||||
'KI',
|
||||
'KN',
|
||||
'KR',
|
||||
'KW',
|
||||
'LA',
|
||||
'LB',
|
||||
'LR',
|
||||
'LY',
|
||||
'LC',
|
||||
'LI',
|
||||
'LK',
|
||||
'LS',
|
||||
'LT',
|
||||
'LU',
|
||||
'LV',
|
||||
'MA',
|
||||
'MC',
|
||||
'MD',
|
||||
'MG',
|
||||
'MV',
|
||||
'MX',
|
||||
'MH',
|
||||
'MK',
|
||||
'ML',
|
||||
'MT',
|
||||
'MM',
|
||||
'ME',
|
||||
'MN',
|
||||
'MZ',
|
||||
'MR',
|
||||
'MU',
|
||||
'MW',
|
||||
'MY',
|
||||
'NA',
|
||||
'NE',
|
||||
'NG',
|
||||
'NI',
|
||||
'NL',
|
||||
'NO',
|
||||
'NP',
|
||||
'NR',
|
||||
'NZ',
|
||||
'OM',
|
||||
'PK',
|
||||
'PS',
|
||||
'PA',
|
||||
'PE',
|
||||
'PH',
|
||||
'PW',
|
||||
'PG',
|
||||
'PL',
|
||||
'KP',
|
||||
'PT',
|
||||
'PY',
|
||||
'QA',
|
||||
'RO',
|
||||
'RU',
|
||||
'RW',
|
||||
'SA',
|
||||
'SD',
|
||||
'SN',
|
||||
'SG',
|
||||
'SB',
|
||||
'SL',
|
||||
'SV',
|
||||
'SM',
|
||||
'SO',
|
||||
'RS',
|
||||
'SS',
|
||||
'ST',
|
||||
'SR',
|
||||
'SK',
|
||||
'SI',
|
||||
'SE',
|
||||
'SZ',
|
||||
'SC',
|
||||
'SY',
|
||||
'TD',
|
||||
'TG',
|
||||
'TH',
|
||||
'TJ',
|
||||
'TM',
|
||||
'TL',
|
||||
'TO',
|
||||
'TT',
|
||||
'TN',
|
||||
'TR',
|
||||
'TV',
|
||||
'TZ',
|
||||
'TW',
|
||||
'UG',
|
||||
'UA',
|
||||
'UY',
|
||||
'US',
|
||||
'UZ',
|
||||
'VA',
|
||||
'VC',
|
||||
'VE',
|
||||
'VN',
|
||||
'VU',
|
||||
'WS',
|
||||
'YE',
|
||||
'ZA',
|
||||
'ZM',
|
||||
'ZW',
|
||||
'AF' => ['name' => 'Afghanistan', 'latitude' => 33.0, 'longitude' => 66.0],
|
||||
'AO' => ['name' => 'Angola', 'latitude' => -12.5, 'longitude' => 18.5],
|
||||
'AL' => ['name' => 'Albania', 'latitude' => 41.0, 'longitude' => 20.0],
|
||||
'AD' => ['name' => 'Andorra', 'latitude' => 42.5, 'longitude' => 1.6],
|
||||
'AE' => ['name' => 'United Arab Emirates', 'latitude' => 24.0, 'longitude' => 54.0],
|
||||
'AR' => ['name' => 'Argentina', 'latitude' => -34.0, 'longitude' => -64.0],
|
||||
'AM' => ['name' => 'Armenia', 'latitude' => 40.0, 'longitude' => 45.0],
|
||||
'AG' => ['name' => 'Antigua and Barbuda', 'latitude' => 17.05, 'longitude' => -61.8],
|
||||
'AU' => ['name' => 'Australia', 'latitude' => -25.0, 'longitude' => 135.0],
|
||||
'AT' => ['name' => 'Austria', 'latitude' => 47.3, 'longitude' => 13.3],
|
||||
'AZ' => ['name' => 'Azerbaijan', 'latitude' => 40.5, 'longitude' => 47.5],
|
||||
'BI' => ['name' => 'Burundi', 'latitude' => -3.5, 'longitude' => 30.0],
|
||||
'BE' => ['name' => 'Belgium', 'latitude' => 50.8, 'longitude' => 4.0],
|
||||
'BJ' => ['name' => 'Benin', 'latitude' => 9.5, 'longitude' => 2.25],
|
||||
'BF' => ['name' => 'Burkina Faso', 'latitude' => 13.0, 'longitude' => -2.0],
|
||||
'BD' => ['name' => 'Bangladesh', 'latitude' => 24.0, 'longitude' => 90.0],
|
||||
'BG' => ['name' => 'Bulgaria', 'latitude' => 43.0, 'longitude' => 25.0],
|
||||
'BH' => ['name' => 'Bahrain', 'latitude' => 26.0, 'longitude' => 50.5],
|
||||
'BS' => ['name' => 'Bahamas', 'latitude' => 24.25, 'longitude' => -76.0],
|
||||
'BA' => ['name' => 'Bosnia and Herzegovina', 'latitude' => 44.0, 'longitude' => 18.0],
|
||||
'BY' => ['name' => 'Belarus', 'latitude' => 53.0, 'longitude' => 28.0],
|
||||
'BZ' => ['name' => 'Belize', 'latitude' => 17.25, 'longitude' => -88.75],
|
||||
'BO' => ['name' => 'Bolivia', 'latitude' => -17.0, 'longitude' => -65.0],
|
||||
'BR' => ['name' => 'Brazil', 'latitude' => -10.0, 'longitude' => -55.0],
|
||||
'BB' => ['name' => 'Barbados', 'latitude' => 13.17, 'longitude' => -59.53],
|
||||
'BN' => ['name' => 'Brunei', 'latitude' => 4.5, 'longitude' => 114.67],
|
||||
'BT' => ['name' => 'Bhutan', 'latitude' => 27.5, 'longitude' => 90.5],
|
||||
'BW' => ['name' => 'Botswana', 'latitude' => -22.0, 'longitude' => 24.0],
|
||||
'CF' => ['name' => 'Central African Republic', 'latitude' => 7.0, 'longitude' => 21.0],
|
||||
'CA' => ['name' => 'Canada', 'latitude' => 60.0, 'longitude' => -95.0],
|
||||
'CH' => ['name' => 'Switzerland', 'latitude' => 47.0, 'longitude' => 8.0],
|
||||
'CL' => ['name' => 'Chile', 'latitude' => -30.0, 'longitude' => -71.0],
|
||||
'CN' => ['name' => 'China', 'latitude' => 35.0, 'longitude' => 105.0],
|
||||
'CI' => ['name' => 'Côte d\'Ivoire', 'latitude' => 8.0, 'longitude' => -5.0],
|
||||
'CM' => ['name' => 'Cameroon', 'latitude' => 6.0, 'longitude' => 12.0],
|
||||
'CD' => ['name' => 'Democratic Republic of the Congo', 'latitude' => -2.5, 'longitude' => 23.5],
|
||||
'CG' => ['name' => 'Republic of the Congo', 'latitude' => -1.0, 'longitude' => 15.0],
|
||||
'CO' => ['name' => 'Colombia', 'latitude' => 4.0, 'longitude' => -72.0],
|
||||
'KM' => ['name' => 'Comoros', 'latitude' => -12.17, 'longitude' => 44.25],
|
||||
'CV' => ['name' => 'Cape Verde', 'latitude' => 16.0, 'longitude' => -24.0],
|
||||
'CR' => ['name' => 'Costa Rica', 'latitude' => 10.0, 'longitude' => -84.0],
|
||||
'CU' => ['name' => 'Cuba', 'latitude' => 21.5, 'longitude' => -80.0],
|
||||
'CY' => ['name' => 'Cyprus', 'latitude' => 35.0, 'longitude' => 33.0],
|
||||
'CZ' => ['name' => 'Czech Republic', 'latitude' => 49.75, 'longitude' => 15.5],
|
||||
'DE' => ['name' => 'Germany', 'latitude' => 51.0, 'longitude' => 9.0],
|
||||
'DJ' => ['name' => 'Djibouti', 'latitude' => 11.5, 'longitude' => 43.0],
|
||||
'DM' => ['name' => 'Dominica', 'latitude' => 15.42, 'longitude' => -61.33],
|
||||
'DK' => ['name' => 'Denmark', 'latitude' => 56.0, 'longitude' => 10.0],
|
||||
'DO' => ['name' => 'Dominican Republic', 'latitude' => 19.0, 'longitude' => -70.67],
|
||||
'DZ' => ['name' => 'Algeria', 'latitude' => 28.0, 'longitude' => 3.0],
|
||||
'EC' => ['name' => 'Ecuador', 'latitude' => -2.0, 'longitude' => -77.5],
|
||||
'EG' => ['name' => 'Egypt', 'latitude' => 27.0, 'longitude' => 30.0],
|
||||
'ER' => ['name' => 'Eritrea', 'latitude' => 15.0, 'longitude' => 39.0],
|
||||
'ES' => ['name' => 'Spain', 'latitude' => 40.0, 'longitude' => -4.0],
|
||||
'EE' => ['name' => 'Estonia', 'latitude' => 59.0, 'longitude' => 26.0],
|
||||
'ET' => ['name' => 'Ethiopia', 'latitude' => 8.0, 'longitude' => 38.0],
|
||||
'FI' => ['name' => 'Finland', 'latitude' => 64.0, 'longitude' => 26.0],
|
||||
'FJ' => ['name' => 'Fiji', 'latitude' => -18.0, 'longitude' => 175.0],
|
||||
'FR' => ['name' => 'France', 'latitude' => 46.0, 'longitude' => 2.0],
|
||||
'FM' => ['name' => 'Micronesia', 'latitude' => 6.92, 'longitude' => 158.25],
|
||||
'GA' => ['name' => 'Gabon', 'latitude' => -1.0, 'longitude' => 11.75],
|
||||
'GB' => ['name' => 'United Kingdom', 'latitude' => 54.0, 'longitude' => -2.0],
|
||||
'GE' => ['name' => 'Georgia', 'latitude' => 42.0, 'longitude' => 43.5],
|
||||
'GH' => ['name' => 'Ghana', 'latitude' => 8.0, 'longitude' => -2.0],
|
||||
'GN' => ['name' => 'Guinea', 'latitude' => 11.0, 'longitude' => -10.0],
|
||||
'GM' => ['name' => 'Gambia', 'latitude' => 13.47, 'longitude' => -16.57],
|
||||
'GW' => ['name' => 'Guinea-Bissau', 'latitude' => 12.0, 'longitude' => -15.0],
|
||||
'GQ' => ['name' => 'Equatorial Guinea', 'latitude' => 2.0, 'longitude' => 10.0],
|
||||
'GR' => ['name' => 'Greece', 'latitude' => 39.0, 'longitude' => 22.0],
|
||||
'GD' => ['name' => 'Grenada', 'latitude' => 12.12, 'longitude' => -61.67],
|
||||
'GT' => ['name' => 'Guatemala', 'latitude' => 15.5, 'longitude' => -90.25],
|
||||
'GY' => ['name' => 'Guyana', 'latitude' => 5.0, 'longitude' => -59.0],
|
||||
'HK' => ['name' => 'Hong Kong', 'latitude' => 22.25, 'longitude' => 114.17],
|
||||
'HN' => ['name' => 'Honduras', 'latitude' => 15.0, 'longitude' => -86.5],
|
||||
'HR' => ['name' => 'Croatia', 'latitude' => 45.17, 'longitude' => 15.5],
|
||||
'HT' => ['name' => 'Haiti', 'latitude' => 19.0, 'longitude' => -72.42],
|
||||
'HU' => ['name' => 'Hungary', 'latitude' => 47.0, 'longitude' => 20.0],
|
||||
'ID' => ['name' => 'Indonesia', 'latitude' => -5.0, 'longitude' => 120.0],
|
||||
'IN' => ['name' => 'India', 'latitude' => 20.0, 'longitude' => 77.0],
|
||||
'IE' => ['name' => 'Ireland', 'latitude' => 53.0, 'longitude' => -8.0],
|
||||
'IR' => ['name' => 'Iran', 'latitude' => 32.0, 'longitude' => 53.0],
|
||||
'IQ' => ['name' => 'Iraq', 'latitude' => 33.0, 'longitude' => 44.0],
|
||||
'IS' => ['name' => 'Iceland', 'latitude' => 65.0, 'longitude' => -18.0],
|
||||
'IL' => ['name' => 'Israel', 'latitude' => 31.5, 'longitude' => 34.75],
|
||||
'IT' => ['name' => 'Italy', 'latitude' => 42.83, 'longitude' => 12.83],
|
||||
'JM' => ['name' => 'Jamaica', 'latitude' => 18.25, 'longitude' => -77.5],
|
||||
'JO' => ['name' => 'Jordan', 'latitude' => 31.0, 'longitude' => 36.0],
|
||||
'JP' => ['name' => 'Japan', 'latitude' => 36.0, 'longitude' => 138.0],
|
||||
'KZ' => ['name' => 'Kazakhstan', 'latitude' => 48.0, 'longitude' => 68.0],
|
||||
'KE' => ['name' => 'Kenya', 'latitude' => 1.0, 'longitude' => 38.0],
|
||||
'KG' => ['name' => 'Kyrgyzstan', 'latitude' => 41.0, 'longitude' => 75.0],
|
||||
'KH' => ['name' => 'Cambodia', 'latitude' => 13.0, 'longitude' => 105.0],
|
||||
'KI' => ['name' => 'Kiribati', 'latitude' => 1.42, 'longitude' => 173.0],
|
||||
'KN' => ['name' => 'Saint Kitts and Nevis', 'latitude' => 17.33, 'longitude' => -62.75],
|
||||
'KR' => ['name' => 'South Korea', 'latitude' => 37.0, 'longitude' => 127.5],
|
||||
'KW' => ['name' => 'Kuwait', 'latitude' => 29.34, 'longitude' => 47.66],
|
||||
'LA' => ['name' => 'Laos', 'latitude' => 18.0, 'longitude' => 105.0],
|
||||
'LB' => ['name' => 'Lebanon', 'latitude' => 33.83, 'longitude' => 35.83],
|
||||
'LR' => ['name' => 'Liberia', 'latitude' => 6.5, 'longitude' => -9.5],
|
||||
'LY' => ['name' => 'Libya', 'latitude' => 25.0, 'longitude' => 17.0],
|
||||
'LC' => ['name' => 'Saint Lucia', 'latitude' => 13.88, 'longitude' => -61.13],
|
||||
'LI' => ['name' => 'Liechtenstein', 'latitude' => 47.17, 'longitude' => 9.53],
|
||||
'LK' => ['name' => 'Sri Lanka', 'latitude' => 7.0, 'longitude' => 81.0],
|
||||
'LS' => ['name' => 'Lesotho', 'latitude' => -29.5, 'longitude' => 28.5],
|
||||
'LT' => ['name' => 'Lithuania', 'latitude' => 56.0, 'longitude' => 24.0],
|
||||
'LU' => ['name' => 'Luxembourg', 'latitude' => 49.75, 'longitude' => 6.17],
|
||||
'LV' => ['name' => 'latitudevia', 'latitude' => 57.0, 'longitude' => 25.0],
|
||||
'MA' => ['name' => 'Morocco', 'latitude' => 32.0, 'longitude' => -5.0],
|
||||
'MC' => ['name' => 'Monaco', 'latitude' => 43.73, 'longitude' => 7.4],
|
||||
'MD' => ['name' => 'Moldova', 'latitude' => 47.0, 'longitude' => 29.0],
|
||||
'MG' => ['name' => 'Madagascar', 'latitude' => -20.0, 'longitude' => 47.0],
|
||||
'MV' => ['name' => 'Maldives', 'latitude' => 3.25, 'longitude' => 73.0],
|
||||
'MX' => ['name' => 'Mexico', 'latitude' => 23.0, 'longitude' => -102.0],
|
||||
'MH' => ['name' => 'Marshall Islands', 'latitude' => 9.0, 'longitude' => 168.0],
|
||||
'MK' => ['name' => 'North Macedonia', 'latitude' => 41.83, 'longitude' => 22.0],
|
||||
'ML' => ['name' => 'Mali', 'latitude' => 17.0, 'longitude' => -4.0],
|
||||
'MT' => ['name' => 'Malta', 'latitude' => 35.83, 'longitude' => 14.58],
|
||||
'MM' => ['name' => 'Myanmar', 'latitude' => 22.0, 'longitude' => 98.0],
|
||||
'ME' => ['name' => 'Montenegro', 'latitude' => 42.5, 'longitude' => 19.3],
|
||||
'MN' => ['name' => 'Mongolia', 'latitude' => 46.0, 'longitude' => 105.0],
|
||||
'MZ' => ['name' => 'Mozambique', 'latitude' => -18.25, 'longitude' => 35.0],
|
||||
'MR' => ['name' => 'Mauritania', 'latitude' => 20.0, 'longitude' => -12.0],
|
||||
'MU' => ['name' => 'Mauritius', 'latitude' => -20.28, 'longitude' => 57.55],
|
||||
'MW' => ['name' => 'Malawi', 'latitude' => -13.5, 'longitude' => 34.0],
|
||||
'MY' => ['name' => 'Malaysia', 'latitude' => 2.5, 'longitude' => 112.5],
|
||||
'NA' => ['name' => 'Namibia', 'latitude' => -22.0, 'longitude' => 17.0],
|
||||
'NE' => ['name' => 'Niger', 'latitude' => 16.0, 'longitude' => 8.0],
|
||||
'NG' => ['name' => 'Nigeria', 'latitude' => 10.0, 'longitude' => 8.0],
|
||||
'NI' => ['name' => 'Nicaragua', 'latitude' => 13.0, 'longitude' => -85.0],
|
||||
'NL' => ['name' => 'Netherlands', 'latitude' => 52.5, 'longitude' => 5.75],
|
||||
'NO' => ['name' => 'Norway', 'latitude' => 62.0, 'longitude' => 10.0],
|
||||
'NP' => ['name' => 'Nepal', 'latitude' => 28.0, 'longitude' => 84.0],
|
||||
'NR' => ['name' => 'Nauru', 'latitude' => -0.53, 'longitude' => 166.92],
|
||||
'NZ' => ['name' => 'New Zealand', 'latitude' => -41.0, 'longitude' => 174.0],
|
||||
'OM' => ['name' => 'Oman', 'latitude' => 21.0, 'longitude' => 57.0],
|
||||
'PK' => ['name' => 'Pakistan', 'latitude' => 30.0, 'longitude' => 70.0],
|
||||
'PS' => ['name' => 'Palestine', 'latitude' => 31.9, 'longitude' => 35.2],
|
||||
'PA' => ['name' => 'Panama', 'latitude' => 9.0, 'longitude' => -80.0],
|
||||
'PE' => ['name' => 'Peru', 'latitude' => -10.0, 'longitude' => -76.0],
|
||||
'PH' => ['name' => 'Philippines', 'latitude' => 13.0, 'longitude' => 122.0],
|
||||
'PW' => ['name' => 'Palau', 'latitude' => 7.5, 'longitude' => 134.5],
|
||||
'PG' => ['name' => 'Papua New Guinea', 'latitude' => -6.0, 'longitude' => 147.0],
|
||||
'PL' => ['name' => 'Poland', 'latitude' => 52.0, 'longitude' => 20.0],
|
||||
'KP' => ['name' => 'North Korea', 'latitude' => 40.0, 'longitude' => 127.0],
|
||||
'PT' => ['name' => 'Portugal', 'latitude' => 39.5, 'longitude' => -8.0],
|
||||
'PY' => ['name' => 'Paraguay', 'latitude' => -23.0, 'longitude' => -58.0],
|
||||
'QA' => ['name' => 'Qatar', 'latitude' => 25.5, 'longitude' => 51.25],
|
||||
'RO' => ['name' => 'Romania', 'latitude' => 46.0, 'longitude' => 25.0],
|
||||
'RU' => ['name' => 'Russia', 'latitude' => 60.0, 'longitude' => 100.0],
|
||||
'RW' => ['name' => 'Rwanda', 'latitude' => -2.0, 'longitude' => 30.0],
|
||||
'SA' => ['name' => 'Saudi Arabia', 'latitude' => 25.0, 'longitude' => 45.0],
|
||||
'SD' => ['name' => 'Sudan', 'latitude' => 15.0, 'longitude' => 30.0],
|
||||
'SN' => ['name' => 'Senegal', 'latitude' => 14.0, 'longitude' => -14.0],
|
||||
'SG' => ['name' => 'Singapore', 'latitude' => 1.37, 'longitude' => 103.8],
|
||||
'SB' => ['name' => 'Solomon Islands', 'latitude' => -8.0, 'longitude' => 159.0],
|
||||
'SL' => ['name' => 'Sierra Leone', 'latitude' => 8.5, 'longitude' => -11.5],
|
||||
'SV' => ['name' => 'El Salvador', 'latitude' => 13.83, 'longitude' => -88.92],
|
||||
'SM' => ['name' => 'San Marino', 'latitude' => 43.77, 'longitude' => 12.42],
|
||||
'SO' => ['name' => 'Somalia', 'latitude' => 10.0, 'longitude' => 49.0],
|
||||
'RS' => ['name' => 'Serbia', 'latitude' => 44.0, 'longitude' => 21.0],
|
||||
'SS' => ['name' => 'South Sudan', 'latitude' => 8.0, 'longitude' => 30.0],
|
||||
'ST' => ['name' => 'São Tomé and Príncipe', 'latitude' => 1.0, 'longitude' => 7.0],
|
||||
'SR' => ['name' => 'Suriname', 'latitude' => 4.0, 'longitude' => -56.0],
|
||||
'SK' => ['name' => 'Slovakia', 'latitude' => 48.67, 'longitude' => 19.5],
|
||||
'SI' => ['name' => 'Slovenia', 'latitude' => 46.0, 'longitude' => 15.0],
|
||||
'SE' => ['name' => 'Sweden', 'latitude' => 62.0, 'longitude' => 15.0],
|
||||
'SZ' => ['name' => 'Eswatini', 'latitude' => -26.5, 'longitude' => 31.5],
|
||||
'SC' => ['name' => 'Seychelles', 'latitude' => -4.58, 'longitude' => 55.67],
|
||||
'SY' => ['name' => 'Syria', 'latitude' => 35.0, 'longitude' => 38.0],
|
||||
'TD' => ['name' => 'Chad', 'latitude' => 15.0, 'longitude' => 19.0],
|
||||
'TG' => ['name' => 'Togo', 'latitude' => 8.0, 'longitude' => 1.17],
|
||||
'TH' => ['name' => 'Thailand', 'latitude' => 15.0, 'longitude' => 100.0],
|
||||
'TJ' => ['name' => 'Tajikistan', 'latitude' => 39.0, 'longitude' => 71.0],
|
||||
'TM' => ['name' => 'Turkmenistan', 'latitude' => 40.0, 'longitude' => 60.0],
|
||||
'TL' => ['name' => 'Timor-Leste', 'latitude' => -8.83, 'longitude' => 125.92],
|
||||
'TO' => ['name' => 'Tonga', 'latitude' => -20.0, 'longitude' => -175.0],
|
||||
'TT' => ['name' => 'Trinidad and Tobago', 'latitude' => 11.0, 'longitude' => -61.0],
|
||||
'TN' => ['name' => 'Tunisia', 'latitude' => 34.0, 'longitude' => 9.0],
|
||||
'TR' => ['name' => 'Turkey', 'latitude' => 39.0, 'longitude' => 35.0],
|
||||
'TV' => ['name' => 'Tuvalu', 'latitude' => -8.0, 'longitude' => 178.0],
|
||||
'TZ' => ['name' => 'Tanzania', 'latitude' => -6.0, 'longitude' => 35.0],
|
||||
'TW' => ['name' => 'Taiwan', 'latitude' => 23.5, 'longitude' => 121.0],
|
||||
'UG' => ['name' => 'Uganda', 'latitude' => 1.0, 'longitude' => 32.0],
|
||||
'UA' => ['name' => 'Ukraine', 'latitude' => 49.0, 'longitude' => 32.0],
|
||||
'UY' => ['name' => 'Uruguay', 'latitude' => -33.0, 'longitude' => -56.0],
|
||||
'US' => ['name' => 'United States', 'latitude' => 38.0, 'longitude' => -97.0],
|
||||
'UZ' => ['name' => 'Uzbekistan', 'latitude' => 41.0, 'longitude' => 64.0],
|
||||
'VA' => ['name' => 'Vatican City', 'latitude' => 41.9, 'longitude' => 12.45],
|
||||
'VC' => ['name' => 'Saint Vincent and the Grenadines', 'latitude' => 13.25, 'longitude' => -61.2],
|
||||
'VE' => ['name' => 'Venezuela', 'latitude' => 8.0, 'longitude' => -66.0],
|
||||
'VN' => ['name' => 'Vietnam', 'latitude' => 16.0, 'longitude' => 106.0],
|
||||
'VU' => ['name' => 'Vanuatu', 'latitude' => -16.0, 'longitude' => 167.0],
|
||||
'WS' => ['name' => 'Samoa', 'latitude' => -13.58, 'longitude' => -172.33],
|
||||
'YE' => ['name' => 'Yemen', 'latitude' => 15.0, 'longitude' => 48.0],
|
||||
'ZA' => ['name' => 'South Africa', 'latitude' => -29.0, 'longitude' => 24.0],
|
||||
'ZM' => ['name' => 'Zambia', 'latitude' => -15.0, 'longitude' => 30.0],
|
||||
'ZW' => ['name' => 'Zimbabwe', 'latitude' => -20.0, 'longitude' => 30.0],
|
||||
];
|
||||
|
||||
@@ -11,7 +11,7 @@ return [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '16.1.0',
|
||||
'version' => '17.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -59,7 +59,7 @@ return [
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '13.1.1',
|
||||
'version' => '15.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -77,7 +77,7 @@ return [
|
||||
[
|
||||
'key' => 'apple',
|
||||
'name' => 'Apple',
|
||||
'version' => '7.1.0',
|
||||
'version' => '9.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'enabled' => true,
|
||||
@@ -134,7 +134,7 @@ return [
|
||||
[
|
||||
'key' => 'react-native',
|
||||
'name' => 'React Native',
|
||||
'version' => '0.6.0',
|
||||
'version' => '0.7.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-react-native',
|
||||
'package' => 'https://npmjs.com/package/react-native-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -217,7 +217,7 @@ return [
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '6.2.0',
|
||||
'version' => '6.2.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
@@ -245,7 +245,7 @@ return [
|
||||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '14.2.0',
|
||||
'version' => '15.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -299,7 +299,7 @@ return [
|
||||
[
|
||||
'key' => 'python',
|
||||
'name' => 'Python',
|
||||
'version' => '6.2.0',
|
||||
'version' => '9.0.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-python',
|
||||
'package' => 'https://pypi.org/project/appwrite/',
|
||||
'enabled' => true,
|
||||
@@ -371,7 +371,7 @@ return [
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '12.2.0',
|
||||
'version' => '14.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
@@ -411,7 +411,7 @@ return [
|
||||
[
|
||||
'key' => 'swift',
|
||||
'name' => 'Swift',
|
||||
'version' => '6.2.0',
|
||||
'version' => '8.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'enabled' => true,
|
||||
|
||||
@@ -3,72 +3,8 @@
|
||||
return [
|
||||
'default' => [
|
||||
'$id' => 'default',
|
||||
'name' => 'Frankfurt',
|
||||
'name' => 'default',
|
||||
'disabled' => false,
|
||||
'flag' => 'de',
|
||||
'default' => true,
|
||||
],
|
||||
'fra' => [
|
||||
'$id' => 'fra',
|
||||
'name' => 'Frankfurt',
|
||||
'disabled' => false,
|
||||
'flag' => 'de',
|
||||
'default' => true,
|
||||
],
|
||||
'nyc' => [
|
||||
'$id' => 'nyc',
|
||||
'name' => 'New York',
|
||||
'disabled' => true,
|
||||
'flag' => 'us',
|
||||
'default' => true,
|
||||
],
|
||||
'sfo' => [
|
||||
'$id' => 'sfo',
|
||||
'name' => 'San Francisco',
|
||||
'disabled' => true,
|
||||
'flag' => 'us',
|
||||
'default' => true,
|
||||
],
|
||||
'blr' => [
|
||||
'$id' => 'blr',
|
||||
'name' => 'Bengaluru',
|
||||
'disabled' => true,
|
||||
'flag' => 'in',
|
||||
'default' => true,
|
||||
],
|
||||
'lon' => [
|
||||
'$id' => 'lon',
|
||||
'name' => 'London',
|
||||
'disabled' => true,
|
||||
'flag' => 'gb',
|
||||
'default' => true,
|
||||
],
|
||||
'ams' => [
|
||||
'$id' => 'ams',
|
||||
'name' => 'Amsterdam',
|
||||
'disabled' => true,
|
||||
'flag' => 'nl',
|
||||
'default' => true,
|
||||
],
|
||||
'sgp' => [
|
||||
'$id' => 'sgp',
|
||||
'name' => 'Singapore',
|
||||
'disabled' => true,
|
||||
'flag' => 'sg',
|
||||
'default' => true,
|
||||
],
|
||||
'tor' => [
|
||||
'$id' => 'tor',
|
||||
'name' => 'Toronto',
|
||||
'disabled' => true,
|
||||
'flag' => 'ca',
|
||||
'default' => true,
|
||||
],
|
||||
'syd' => [
|
||||
'$id' => 'syd',
|
||||
'name' => 'Sydney',
|
||||
'disabled' => true,
|
||||
'flag' => 'au',
|
||||
'default' => true,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -9268,7 +9268,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"entrypoint": {
|
||||
@@ -9889,7 +9889,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"entrypoint": {
|
||||
@@ -10140,7 +10140,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
@@ -10510,17 +10510,18 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch"
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
"activate": {
|
||||
@@ -19352,8 +19353,7 @@
|
||||
"description": "Project Region.",
|
||||
"x-example": "default",
|
||||
"enum": [
|
||||
"default",
|
||||
"fra"
|
||||
"default"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
@@ -24730,6 +24730,11 @@
|
||||
"description": "Is site enabled? When set to 'disabled', users cannot access the site but Server SDKs with and API key can still access the site. No data is lost when this is toggled.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -25360,6 +25365,11 @@
|
||||
"description": "Is site enabled? When set to 'disabled', users cannot access the site but Server SDKs with and API key can still access the site. No data is lost when this is toggled.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -25698,7 +25708,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
@@ -26068,18 +26078,19 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch",
|
||||
"commit"
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
"activate": {
|
||||
@@ -36863,6 +36874,11 @@
|
||||
"description": "Is the site deployed with the latest configuration? This is set to false if you've changed an environment variables, entrypoint, commands, or other settings that needs redeploy to be applied. When the value is false, redeploy the site to update it with the latest configuration.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"framework": {
|
||||
"type": "string",
|
||||
"description": "Site framework.",
|
||||
@@ -36873,6 +36889,36 @@
|
||||
"description": "Site's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"deploymentScreenshotLight": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with light theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentScreenshotDark": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with dark theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Site's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"vars": {
|
||||
"type": "array",
|
||||
"description": "Site variables.",
|
||||
@@ -36955,8 +37001,15 @@
|
||||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"deploymentScreenshotLight",
|
||||
"deploymentScreenshotDark",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"vars",
|
||||
"timeout",
|
||||
"installCommand",
|
||||
@@ -37168,7 +37221,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"runtime": {
|
||||
@@ -37181,6 +37234,26 @@
|
||||
"description": "Function's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Function's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"description": "Allowed permission scopes.",
|
||||
@@ -37273,6 +37346,10 @@
|
||||
"logging",
|
||||
"runtime",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"scopes",
|
||||
"vars",
|
||||
"events",
|
||||
@@ -37924,13 +38001,19 @@
|
||||
"type": "string",
|
||||
"description": "Default output directory of build.",
|
||||
"x-example": ".\/dist"
|
||||
},
|
||||
"fallbackFile": {
|
||||
"type": "string",
|
||||
"description": "Name of fallback file to use instead of 404 page. If null, Appwrite 404 page will be displayed.",
|
||||
"x-example": "index.html"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"installCommand",
|
||||
"buildCommand",
|
||||
"outputDirectory"
|
||||
"outputDirectory",
|
||||
"fallbackFile"
|
||||
]
|
||||
},
|
||||
"deployment": {
|
||||
@@ -37984,6 +38067,12 @@
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"totalSize": {
|
||||
"type": "integer",
|
||||
"description": "The total size in bytes (source and build output).",
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"buildId": {
|
||||
"type": "string",
|
||||
"description": "The current build ID.",
|
||||
@@ -38006,7 +38095,7 @@
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"waiting\", \"ready\", and \"failed\".",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"buildLogs": {
|
||||
@@ -38081,6 +38170,7 @@
|
||||
"entrypoint",
|
||||
"sourceSize",
|
||||
"buildSize",
|
||||
"totalSize",
|
||||
"buildId",
|
||||
"activate",
|
||||
"screenshotLight",
|
||||
|
||||
@@ -8355,7 +8355,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"entrypoint": {
|
||||
@@ -8751,7 +8751,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"entrypoint": {
|
||||
@@ -9005,7 +9005,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
@@ -9379,17 +9379,18 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch"
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
"activate": {
|
||||
@@ -16827,6 +16828,11 @@
|
||||
"description": "Is site enabled? When set to 'disabled', users cannot access the site but Server SDKs with and API key can still access the site. No data is lost when this is toggled.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -17232,6 +17238,11 @@
|
||||
"description": "Is site enabled? When set to 'disabled', users cannot access the site but Server SDKs with and API key can still access the site. No data is lost when this is toggled.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -17573,7 +17584,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
@@ -17947,18 +17958,19 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch",
|
||||
"commit"
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
"activate": {
|
||||
@@ -27411,6 +27423,11 @@
|
||||
"description": "Is the site deployed with the latest configuration? This is set to false if you've changed an environment variables, entrypoint, commands, or other settings that needs redeploy to be applied. When the value is false, redeploy the site to update it with the latest configuration.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"framework": {
|
||||
"type": "string",
|
||||
"description": "Site framework.",
|
||||
@@ -27421,6 +27438,36 @@
|
||||
"description": "Site's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"deploymentScreenshotLight": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with light theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentScreenshotDark": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with dark theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Site's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"vars": {
|
||||
"type": "array",
|
||||
"description": "Site variables.",
|
||||
@@ -27503,8 +27550,15 @@
|
||||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"deploymentScreenshotLight",
|
||||
"deploymentScreenshotDark",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"vars",
|
||||
"timeout",
|
||||
"installCommand",
|
||||
@@ -27565,7 +27619,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"runtime": {
|
||||
@@ -27578,6 +27632,26 @@
|
||||
"description": "Function's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Function's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"description": "Allowed permission scopes.",
|
||||
@@ -27670,6 +27744,10 @@
|
||||
"logging",
|
||||
"runtime",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"scopes",
|
||||
"vars",
|
||||
"events",
|
||||
@@ -27823,13 +27901,19 @@
|
||||
"type": "string",
|
||||
"description": "Default output directory of build.",
|
||||
"x-example": ".\/dist"
|
||||
},
|
||||
"fallbackFile": {
|
||||
"type": "string",
|
||||
"description": "Name of fallback file to use instead of 404 page. If null, Appwrite 404 page will be displayed.",
|
||||
"x-example": "index.html"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"installCommand",
|
||||
"buildCommand",
|
||||
"outputDirectory"
|
||||
"outputDirectory",
|
||||
"fallbackFile"
|
||||
]
|
||||
},
|
||||
"deployment": {
|
||||
@@ -27883,6 +27967,12 @@
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"totalSize": {
|
||||
"type": "integer",
|
||||
"description": "The total size in bytes (source and build output).",
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"buildId": {
|
||||
"type": "string",
|
||||
"description": "The current build ID.",
|
||||
@@ -27905,7 +27995,7 @@
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"waiting\", \"ready\", and \"failed\".",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"buildLogs": {
|
||||
@@ -27980,6 +28070,7 @@
|
||||
"entrypoint",
|
||||
"sourceSize",
|
||||
"buildSize",
|
||||
"totalSize",
|
||||
"buildId",
|
||||
"activate",
|
||||
"screenshotLight",
|
||||
|
||||
@@ -9425,7 +9425,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
@@ -10061,7 +10061,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
@@ -10322,7 +10322,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
@@ -10687,18 +10687,19 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"default": null,
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch"
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"default": null,
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
@@ -19822,8 +19823,7 @@
|
||||
"default": "default",
|
||||
"x-example": "default",
|
||||
"enum": [
|
||||
"default",
|
||||
"fra"
|
||||
"default"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
@@ -25234,6 +25234,12 @@
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -25878,6 +25884,12 @@
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -26229,7 +26241,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
@@ -26596,19 +26608,20 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"default": null,
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch",
|
||||
"commit"
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"default": null,
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
@@ -37443,6 +37456,11 @@
|
||||
"description": "Is the site deployed with the latest configuration? This is set to false if you've changed an environment variables, entrypoint, commands, or other settings that needs redeploy to be applied. When the value is false, redeploy the site to update it with the latest configuration.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"framework": {
|
||||
"type": "string",
|
||||
"description": "Site framework.",
|
||||
@@ -37453,6 +37471,36 @@
|
||||
"description": "Site's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"deploymentScreenshotLight": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with light theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentScreenshotDark": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with dark theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Site's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"vars": {
|
||||
"type": "array",
|
||||
"description": "Site variables.",
|
||||
@@ -37536,8 +37584,15 @@
|
||||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"deploymentScreenshotLight",
|
||||
"deploymentScreenshotDark",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"vars",
|
||||
"timeout",
|
||||
"installCommand",
|
||||
@@ -37751,7 +37806,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"runtime": {
|
||||
@@ -37764,6 +37819,26 @@
|
||||
"description": "Function's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Function's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"description": "Allowed permission scopes.",
|
||||
@@ -37857,6 +37932,10 @@
|
||||
"logging",
|
||||
"runtime",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"scopes",
|
||||
"vars",
|
||||
"events",
|
||||
@@ -38511,13 +38590,19 @@
|
||||
"type": "string",
|
||||
"description": "Default output directory of build.",
|
||||
"x-example": ".\/dist"
|
||||
},
|
||||
"fallbackFile": {
|
||||
"type": "string",
|
||||
"description": "Name of fallback file to use instead of 404 page. If null, Appwrite 404 page will be displayed.",
|
||||
"x-example": "index.html"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"installCommand",
|
||||
"buildCommand",
|
||||
"outputDirectory"
|
||||
"outputDirectory",
|
||||
"fallbackFile"
|
||||
]
|
||||
},
|
||||
"deployment": {
|
||||
@@ -38571,6 +38656,12 @@
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"totalSize": {
|
||||
"type": "integer",
|
||||
"description": "The total size in bytes (source and build output).",
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"buildId": {
|
||||
"type": "string",
|
||||
"description": "The current build ID.",
|
||||
@@ -38593,7 +38684,7 @@
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"waiting\", \"ready\", and \"failed\".",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"buildLogs": {
|
||||
@@ -38668,6 +38759,7 @@
|
||||
"entrypoint",
|
||||
"sourceSize",
|
||||
"buildSize",
|
||||
"totalSize",
|
||||
"buildId",
|
||||
"activate",
|
||||
"screenshotLight",
|
||||
|
||||
@@ -8509,7 +8509,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
@@ -8924,7 +8924,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
@@ -9188,7 +9188,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
@@ -9557,18 +9557,19 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"default": null,
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch"
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"default": null,
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
@@ -17297,6 +17298,12 @@
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -17720,6 +17727,12 @@
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"default": true,
|
||||
"x-example": false
|
||||
},
|
||||
"timeout": {
|
||||
"type": "integer",
|
||||
"description": "Maximum request time in seconds.",
|
||||
@@ -18074,7 +18087,7 @@
|
||||
},
|
||||
{
|
||||
"name": "queries",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, buildDuration, status, activate, type",
|
||||
"description": "Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https:\/\/appwrite.io\/docs\/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
@@ -18445,19 +18458,20 @@
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"description": "Type of reference passed. Allowed values are: branch",
|
||||
"description": "Type of reference passed. Allowed values are: branch, commit",
|
||||
"default": null,
|
||||
"x-example": "branch",
|
||||
"enum": [
|
||||
"branch",
|
||||
"commit"
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
"type": "string",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name",
|
||||
"description": "VCS reference to create deployment from. Depending on type this can be: branch name, commit hash",
|
||||
"default": null,
|
||||
"x-example": "<REFERENCE>"
|
||||
},
|
||||
@@ -27962,6 +27976,11 @@
|
||||
"description": "Is the site deployed with the latest configuration? This is set to false if you've changed an environment variables, entrypoint, commands, or other settings that needs redeploy to be applied. When the value is false, redeploy the site to update it with the latest configuration.",
|
||||
"x-example": false
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"framework": {
|
||||
"type": "string",
|
||||
"description": "Site framework.",
|
||||
@@ -27972,6 +27991,36 @@
|
||||
"description": "Site's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"deploymentScreenshotLight": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with light theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentScreenshotDark": {
|
||||
"type": "string",
|
||||
"description": "Screenshot of active deployment with dark theme preference file ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Site's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"vars": {
|
||||
"type": "array",
|
||||
"description": "Site variables.",
|
||||
@@ -28055,8 +28104,15 @@
|
||||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"deploymentScreenshotLight",
|
||||
"deploymentScreenshotDark",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"vars",
|
||||
"timeout",
|
||||
"installCommand",
|
||||
@@ -28117,7 +28173,7 @@
|
||||
},
|
||||
"logging": {
|
||||
"type": "boolean",
|
||||
"description": "Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.",
|
||||
"description": "When disabled, executions will exclude logs and errors, and will be slightly faster.",
|
||||
"x-example": false
|
||||
},
|
||||
"runtime": {
|
||||
@@ -28130,6 +28186,26 @@
|
||||
"description": "Function's active deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"deploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Active deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentId": {
|
||||
"type": "string",
|
||||
"description": "Function's latest deployment ID.",
|
||||
"x-example": "5e5ea5c16897e"
|
||||
},
|
||||
"latestDeploymentCreatedAt": {
|
||||
"type": "string",
|
||||
"description": "Latest deployment creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"latestDeploymentStatus": {
|
||||
"type": "string",
|
||||
"description": "Status of latest deployment. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "array",
|
||||
"description": "Allowed permission scopes.",
|
||||
@@ -28223,6 +28299,10 @@
|
||||
"logging",
|
||||
"runtime",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
"latestDeploymentId",
|
||||
"latestDeploymentCreatedAt",
|
||||
"latestDeploymentStatus",
|
||||
"scopes",
|
||||
"vars",
|
||||
"events",
|
||||
@@ -28377,13 +28457,19 @@
|
||||
"type": "string",
|
||||
"description": "Default output directory of build.",
|
||||
"x-example": ".\/dist"
|
||||
},
|
||||
"fallbackFile": {
|
||||
"type": "string",
|
||||
"description": "Name of fallback file to use instead of 404 page. If null, Appwrite 404 page will be displayed.",
|
||||
"x-example": "index.html"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"installCommand",
|
||||
"buildCommand",
|
||||
"outputDirectory"
|
||||
"outputDirectory",
|
||||
"fallbackFile"
|
||||
]
|
||||
},
|
||||
"deployment": {
|
||||
@@ -28437,6 +28523,12 @@
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"totalSize": {
|
||||
"type": "integer",
|
||||
"description": "The total size in bytes (source and build output).",
|
||||
"x-example": 128,
|
||||
"format": "int32"
|
||||
},
|
||||
"buildId": {
|
||||
"type": "string",
|
||||
"description": "The current build ID.",
|
||||
@@ -28459,7 +28551,7 @@
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"waiting\", \"ready\", and \"failed\".",
|
||||
"description": "The deployment status. Possible values are \"waiting\", \"processing\", \"building\", \"ready\", and \"failed\".",
|
||||
"x-example": "ready"
|
||||
},
|
||||
"buildLogs": {
|
||||
@@ -28534,6 +28626,7 @@
|
||||
"entrypoint",
|
||||
"sourceSize",
|
||||
"buildSize",
|
||||
"totalSize",
|
||||
"buildId",
|
||||
"activate",
|
||||
"screenshotLight",
|
||||
|
||||
@@ -16,6 +16,16 @@ if (System::getEnv('_APP_ENV') === 'development') {
|
||||
|
||||
$url = $protocol . '://' . $hostname;
|
||||
|
||||
class UseCases
|
||||
{
|
||||
public const PORTFOLIO = 'portfolio';
|
||||
public const STARTER = 'starter';
|
||||
public const EVENTS = 'events';
|
||||
public const ECOMMERCE = 'ecommerce';
|
||||
public const DOCUMENTATION = 'documentation';
|
||||
public const BLOG = 'blog';
|
||||
}
|
||||
|
||||
const TEMPLATE_FRAMEWORKS = [
|
||||
'SVELTEKIT' => [
|
||||
'key' => 'sveltekit',
|
||||
@@ -125,6 +135,15 @@ const TEMPLATE_FRAMEWORKS = [
|
||||
'outputDirectory' => './dist',
|
||||
'fallbackFile' => 'index.html',
|
||||
],
|
||||
'OTHER' => [
|
||||
'key' => 'other',
|
||||
'name' => 'Other',
|
||||
'installCommand' => '',
|
||||
'buildCommand' => '',
|
||||
'buildRuntime' => 'node-22',
|
||||
'adapter' => 'static',
|
||||
'outputDirectory' => './',
|
||||
],
|
||||
];
|
||||
|
||||
function getFramework(string $frameworkEnum, array $overrides)
|
||||
@@ -135,14 +154,128 @@ function getFramework(string $frameworkEnum, array $overrides)
|
||||
|
||||
return [
|
||||
[
|
||||
'key' => 'template-for-onelink',
|
||||
'name' => 'Onelink template',
|
||||
'useCases' => ['starter'],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-onelink-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-onelink-light.png',
|
||||
'key' => 'vitepress',
|
||||
'name' => 'Vitepress',
|
||||
'useCases' => [UseCases::DOCUMENTATION],
|
||||
'screenshotDark' => $url . '/images/sites/templates/vitepress-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/vitepress-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('VITE', [
|
||||
'providerRootDirectory' => './vite/vitepress',
|
||||
'outputDirectory' => '404.html',
|
||||
'installCommand' => 'npm i vitepress && npm install',
|
||||
'buildCommand' => 'npm run docs:build',
|
||||
'outputDirectory' => './.vitepress/dist',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'vuepress',
|
||||
'name' => 'Vuepress',
|
||||
'useCases' => [UseCases::DOCUMENTATION],
|
||||
'screenshotDark' => $url . '/images/sites/templates/vuepress-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/vuepress-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('VUE', [
|
||||
'providerRootDirectory' => './vue/vuepress',
|
||||
'outputDirectory' => '404.html',
|
||||
'installCommand' => 'npm install',
|
||||
'buildCommand' => 'npm run build',
|
||||
'outputDirectory' => './src/.vuepress/dist',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'docusaurus',
|
||||
'name' => 'Docusaurus',
|
||||
'useCases' => [UseCases::DOCUMENTATION],
|
||||
'screenshotDark' => $url . '/images/sites/templates/docusaurus-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/docusaurus-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('REACT', [
|
||||
'providerRootDirectory' => './react/docusaurus',
|
||||
'outputDirectory' => '404.html',
|
||||
'installCommand' => 'npm install',
|
||||
'buildCommand' => 'npm run build',
|
||||
'outputDirectory' => './build',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'nxt-lnk',
|
||||
'name' => 'Nxt Lnk',
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('NEXTJS', [
|
||||
'providerRootDirectory' => './nextjs/nxtlnk',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'magic-portfolio',
|
||||
'name' => 'Magic Portfolio',
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('NEXTJS', [
|
||||
'providerRootDirectory' => './nextjs/magic-portfolio',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'littlelink',
|
||||
'name' => 'LittleLink',
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('OTHER', [
|
||||
'providerRootDirectory' => './other/littlelink',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'logspot',
|
||||
'name' => 'Logspot',
|
||||
'useCases' => [UseCases::BLOG],
|
||||
'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/logspot-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('NUXT', [
|
||||
'providerRootDirectory' => './onelink',
|
||||
'providerRootDirectory' => './nuxt/logspot',
|
||||
'buildCommand' => 'npm run generate',
|
||||
'outputDirectory' => './dist',
|
||||
'adapter' => 'static',
|
||||
@@ -150,20 +283,116 @@ return [
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'Meldiron',
|
||||
'providerVersion' => '0.1.*',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'astro-nano',
|
||||
'name' => 'Astro Nano',
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-nano-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-nano-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ASTRO', [
|
||||
'providerRootDirectory' => './astro/nano',
|
||||
'outputDirectory' => './dist',
|
||||
'adapter' => 'static',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'astro-starlight',
|
||||
'name' => 'Astro Starlight',
|
||||
'useCases' => [UseCases::DOCUMENTATION],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-starlight-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-starlight-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ASTRO', [
|
||||
'providerRootDirectory' => './astro/starlight',
|
||||
'outputDirectory' => './dist',
|
||||
'adapter' => 'static',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'astro-sphere',
|
||||
'name' => 'Astro Sphere',
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-sphere-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-sphere-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ASTRO', [
|
||||
'providerRootDirectory' => './astro/sphere',
|
||||
'outputDirectory' => './dist',
|
||||
'adapter' => 'static',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'astro-starlog',
|
||||
'name' => 'Astro Starlog',
|
||||
'useCases' => [UseCases::BLOG],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-starlog-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-starlog-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ASTRO', [
|
||||
'providerRootDirectory' => './astro/starlog',
|
||||
'outputDirectory' => './dist',
|
||||
'adapter' => 'static',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'onelink',
|
||||
'name' => 'Onelink',
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/onelink-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/onelink-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('NUXT', [
|
||||
'providerRootDirectory' => './nuxt/onelink',
|
||||
'buildCommand' => 'npm run generate',
|
||||
'outputDirectory' => './dist',
|
||||
'adapter' => 'static',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'starter-for-flutter',
|
||||
'name' => 'Flutter starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-flutter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-flutter-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('FLUTTER', [
|
||||
'providerRootDirectory' => './',
|
||||
'buildCommand' => 'sh build.sh',
|
||||
'buildCommand' => 'bash build.sh',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
@@ -200,7 +429,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-js',
|
||||
'name' => 'JavaScript starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-js-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-js-light.png',
|
||||
'frameworks' => [
|
||||
@@ -242,14 +471,14 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-angular',
|
||||
'name' => 'Angular starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-angular-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-angular-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ANGULAR', [
|
||||
'providerRootDirectory' => './',
|
||||
'outputDirectory' => './dist/angular-starter-kit-for-appwrite/browser',
|
||||
'buildCommand' => 'sh prepare-env.sh && npm run build'
|
||||
'buildCommand' => 'bash prepare-env.sh && npm run build'
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
@@ -286,7 +515,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-svelte',
|
||||
'name' => 'Svelte starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-svelte-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-svelte-light.png',
|
||||
'frameworks' => [
|
||||
@@ -328,7 +557,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-react',
|
||||
'name' => 'React starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-react-light.png',
|
||||
'frameworks' => [
|
||||
@@ -370,7 +599,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-vue',
|
||||
'name' => 'Vue starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-vue-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-vue-light.png',
|
||||
'frameworks' => [
|
||||
@@ -412,7 +641,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-react-native',
|
||||
'name' => 'React Native starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-native-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-react-native-light.png',
|
||||
'frameworks' => [
|
||||
@@ -455,7 +684,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-nextjs',
|
||||
'name' => 'Next.js starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-nextjs-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-nextjs-light.png',
|
||||
'frameworks' => [
|
||||
@@ -497,7 +726,7 @@ return [
|
||||
[
|
||||
'key' => 'starter-for-nuxt',
|
||||
'name' => 'Nuxt starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-nuxt-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-nuxt-light.png',
|
||||
'frameworks' => [
|
||||
@@ -539,7 +768,7 @@ return [
|
||||
[
|
||||
'key' => 'template-for-event',
|
||||
'name' => 'Event template',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::EVENTS],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-event-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-event-light.png',
|
||||
'frameworks' => [
|
||||
@@ -575,7 +804,7 @@ return [
|
||||
[
|
||||
'key' => 'template-for-portfolio',
|
||||
'name' => 'Portfolio template',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-portfolio-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-portfolio-light.png',
|
||||
'frameworks' => [
|
||||
@@ -592,7 +821,7 @@ return [
|
||||
[
|
||||
'key' => 'template-for-store',
|
||||
'name' => 'Store template',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::ECOMMERCE],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-store-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-store-light.png',
|
||||
'frameworks' => [
|
||||
@@ -634,7 +863,7 @@ return [
|
||||
[
|
||||
'key' => 'template-for-blog',
|
||||
'name' => 'Blog template',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::BLOG],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-blog-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-blog-light.png',
|
||||
'frameworks' => [
|
||||
@@ -651,7 +880,7 @@ return [
|
||||
[
|
||||
'key' => 'astro-starter',
|
||||
'name' => 'Astro starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-starter-light.png',
|
||||
'frameworks' => [
|
||||
@@ -668,7 +897,7 @@ return [
|
||||
[
|
||||
'key' => 'remix-starter',
|
||||
'name' => 'Remix starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/remix-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/remix-starter-light.png',
|
||||
'frameworks' => [
|
||||
@@ -682,72 +911,4 @@ return [
|
||||
'providerVersion' => '0.2.*',
|
||||
'variables' => [],
|
||||
],
|
||||
[
|
||||
'key' => 'flutter-starter',
|
||||
'name' => 'Flutter starter',
|
||||
'useCases' => ['starter'],
|
||||
'screenshotDark' => $url . '/images/sites/templates/flutter-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/flutter-starter-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('FLUTTER', [
|
||||
'providerRootDirectory' => './flutter/starter',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.2.*',
|
||||
'variables' => [],
|
||||
],
|
||||
[
|
||||
'key' => 'nextjs-starter',
|
||||
'name' => 'Next.js starter website',
|
||||
'useCases' => ['starter'],
|
||||
'screenshotDark' => $url . '/images/sites/templates/nextjs-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/nextjs-starter-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('NEXTJS', [
|
||||
'providerRootDirectory' => './nextjs/starter',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.2.*',
|
||||
'variables' => [],
|
||||
],
|
||||
[
|
||||
'key' => 'nuxt-starter',
|
||||
'name' => 'Nuxt starter website',
|
||||
'useCases' => ['starter'],
|
||||
'screenshotDark' => $url . '/images/sites/templates/nuxt-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/nuxt-starter-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('NUXT', [
|
||||
'providerRootDirectory' => './nuxt/starter',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.2.*',
|
||||
'variables' => [],
|
||||
],
|
||||
[
|
||||
'key' => 'sveltekit-starter',
|
||||
'name' => 'SvelteKit starter website',
|
||||
'useCases' => ['starter'],
|
||||
'screenshotDark' => $url . '/images/sites/templates/sveltekit-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/sveltekit-starter-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('SVELTEKIT', [
|
||||
'providerRootDirectory' => './sveltekit/starter',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.2.*',
|
||||
'variables' => [],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -3355,7 +3355,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
$processDocument($collection, $document);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, $operations)
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations)
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getInternalId(), $collection->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_STORAGE), 1); // per collection
|
||||
|
||||
@@ -3520,7 +3520,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, $operations)
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
@@ -3661,7 +3661,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
$processDocument($collection, $document);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, $operations)
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
@@ -3959,7 +3959,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
$setCollection($collection, $newDocument);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, $operations)
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
|
||||
@@ -118,7 +118,7 @@ App::get('/v1/locale/countries')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
$list = Config::getParam('locale-countries'); /* @var $list array */
|
||||
$list = array_keys(Config::getParam('locale-countries')); /* @var $list array */
|
||||
$output = [];
|
||||
|
||||
foreach ($list as $value) {
|
||||
@@ -229,7 +229,7 @@ App::get('/v1/locale/continents')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
$list = Config::getParam('locale-continents');
|
||||
$list = array_keys(Config::getParam('locale-continents'));
|
||||
|
||||
foreach ($list as $value) {
|
||||
$output[] = new Document([
|
||||
|
||||
@@ -2936,7 +2936,7 @@ App::post('/v1/messaging/messages/email')
|
||||
break;
|
||||
case MessageStatus::SCHEDULED:
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
@@ -3058,7 +3058,7 @@ App::post('/v1/messaging/messages/sms')
|
||||
break;
|
||||
case MessageStatus::SCHEDULED:
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
@@ -3275,7 +3275,7 @@ App::post('/v1/messaging/messages/push')
|
||||
break;
|
||||
case MessageStatus::SCHEDULED:
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
@@ -3661,7 +3661,7 @@ App::patch('/v1/messaging/messages/email/:messageId')
|
||||
|
||||
if (\is_null($currentScheduledAt) && !\is_null($scheduledAt)) {
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
@@ -3862,7 +3862,7 @@ App::patch('/v1/messaging/messages/sms/:messageId')
|
||||
|
||||
if (\is_null($currentScheduledAt) && !\is_null($scheduledAt)) {
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
@@ -4035,7 +4035,7 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
|
||||
if (\is_null($currentScheduledAt) && !\is_null($scheduledAt)) {
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'message',
|
||||
'resourceId' => $message->getId(),
|
||||
'resourceInternalId' => $message->getInternalId(),
|
||||
|
||||
@@ -232,6 +232,8 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
'entrypoint' => $resource->getAttribute('entrypoint', ''),
|
||||
'buildCommands' => \implode(' && ', $commands),
|
||||
'buildOutput' => $resource->getAttribute('outputDirectory', ''),
|
||||
'adapter' => $resource->getAttribute('adapter', ''),
|
||||
'fallbackFile' => $resource->getAttribute('fallbackFile', ''),
|
||||
'type' => 'vcs',
|
||||
'installationId' => $installationId,
|
||||
'installationInternalId' => $installationInternalId,
|
||||
@@ -253,6 +255,13 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
'activate' => $activate,
|
||||
]));
|
||||
|
||||
$resource = $resource
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
|
||||
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
$projectId = $project->getId();
|
||||
|
||||
@@ -277,6 +286,8 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
|
||||
@@ -302,6 +313,8 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
} catch (Duplicate $err) {
|
||||
@@ -331,6 +344,8 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
} catch (Duplicate $err) {
|
||||
@@ -724,7 +739,7 @@ App::post('/v1/vcs/github/installations/:installationId/detections')
|
||||
}
|
||||
|
||||
$frameworks = Config::getParam('frameworks');
|
||||
if (!\in_array($framework, array_keys($frameworks), true)) {
|
||||
if (!\in_array($framework, \array_keys($frameworks), true)) {
|
||||
$framework = 'other';
|
||||
}
|
||||
$output->setAttribute('framework', $framework);
|
||||
@@ -876,7 +891,7 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories')
|
||||
}
|
||||
|
||||
$frameworks = Config::getParam('frameworks');
|
||||
if (!\in_array($framework, array_keys($frameworks), true)) {
|
||||
if (!\in_array($framework, \array_keys($frameworks), true)) {
|
||||
$framework = 'other';
|
||||
}
|
||||
$repo['framework'] = $framework;
|
||||
|
||||
@@ -261,7 +261,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
};
|
||||
|
||||
// Static site enforced runtime
|
||||
if ($resource->getAttribute('adapter', '') === 'static') {
|
||||
if ($deployment->getAttribute('adapter', '') === 'static') {
|
||||
$runtime = $runtimes['static-1'] ?? null;
|
||||
}
|
||||
|
||||
@@ -269,8 +269,13 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $resource->getAttribute('runtime', '') . '" is not supported');
|
||||
}
|
||||
|
||||
if ($deployment->getAttribute('status') !== 'ready') {
|
||||
throw new AppwriteException(AppwriteException::BUILD_NOT_READY);
|
||||
$allowAnyStatus = !\is_null($apiKey) && $apiKey->isDeploymentStatusIgnored();
|
||||
if (!$allowAnyStatus && $deployment->getAttribute('status') !== 'ready') {
|
||||
if ($deployment->getAttribute('status') === 'failed') {
|
||||
throw new AppwriteException(AppwriteException::BUILD_FAILED);
|
||||
} else {
|
||||
throw new AppwriteException(AppwriteException::BUILD_NOT_READY);
|
||||
}
|
||||
}
|
||||
|
||||
if ($type === 'function') {
|
||||
@@ -410,8 +415,8 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
]);
|
||||
|
||||
// SPA fallbackFile override
|
||||
if ($resource->getAttribute('adapter', '') === 'static' && $resource->getAttribute('fallbackFile', '') !== '') {
|
||||
$vars['OPEN_RUNTIMES_STATIC_FALLBACK'] = $resource->getAttribute('fallbackFile', '');
|
||||
if ($deployment->getAttribute('adapter', '') === 'static' && $deployment->getAttribute('fallbackFile', '') !== '') {
|
||||
$vars['OPEN_RUNTIMES_STATIC_FALLBACK'] = $deployment->getAttribute('fallbackFile', '');
|
||||
}
|
||||
|
||||
/** Execute function */
|
||||
@@ -438,7 +443,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
$startCommand = $runtime['startCommand'];
|
||||
|
||||
if (!is_null($framework)) {
|
||||
$adapter = ($framework['adapters'] ?? [])[$resource->getAttribute('adapter', '')] ?? null;
|
||||
$adapter = ($framework['adapters'] ?? [])[$deployment->getAttribute('adapter', '')] ?? null;
|
||||
if (!is_null($adapter) && isset($adapter['startCommand'])) {
|
||||
$startCommand = $adapter['startCommand'];
|
||||
}
|
||||
@@ -473,7 +478,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
);
|
||||
|
||||
// Branded 404 override
|
||||
if ($executionResponse['statusCode'] === 404 && $resource->getAttribute('adapter', '') === 'static') {
|
||||
if ($executionResponse['statusCode'] === 404 && $deployment->getAttribute('adapter', '') === 'static') {
|
||||
$layout = new View(__DIR__ . '/../views/general/404.phtml');
|
||||
$executionResponse['body'] = $layout->render();
|
||||
$executionResponse['headers']['content-length'] = \strlen($executionResponse['body']);
|
||||
@@ -736,6 +741,12 @@ App::init()
|
||||
]);
|
||||
}
|
||||
|
||||
$owner = '';
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain) && \str_ends_with($domain->get(), $functionsDomain)) {
|
||||
$owner = 'Appwrite';
|
||||
}
|
||||
|
||||
if ($domainDocument->isEmpty()) {
|
||||
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
|
||||
$domainDocument = new Document([
|
||||
@@ -744,9 +755,11 @@ App::init()
|
||||
'domain' => $domain->get(),
|
||||
'type' => 'api',
|
||||
'status' => 'verifying',
|
||||
'projectId' => 'console',
|
||||
'projectInternalId' => 'console',
|
||||
'projectId' => $console->getId(),
|
||||
'projectInternalId' => $console->getInternalId(),
|
||||
'search' => implode(' ', [$ruleId, $domain->get()]),
|
||||
'owner' => $owner,
|
||||
'region' => $console->getAttribute('region')
|
||||
]);
|
||||
|
||||
$domainDocument = $dbForPlatform->createDocument('rules', $domainDocument);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Config\Config;
|
||||
|
||||
Config::load('template-runtimes', __DIR__ . '/../config/template-runtimes.php');
|
||||
Config::load('events', __DIR__ . '/../config/events.php');
|
||||
Config::load('auth', __DIR__ . '/../config/auth.php');
|
||||
Config::load('apis', __DIR__ . '/../config/apis.php'); // List of APIs
|
||||
Config::load('errors', __DIR__ . '/../config/errors.php');
|
||||
Config::load('oAuthProviders', __DIR__ . '/../config/oAuthProviders.php');
|
||||
Config::load('platforms', __DIR__ . '/../config/platforms.php');
|
||||
Config::load('console', __DIR__ . '/../config/console.php');
|
||||
Config::load('collections', __DIR__ . '/../config/collections.php');
|
||||
Config::load('frameworks', __DIR__ . '/../config/frameworks.php');
|
||||
Config::load('runtimes', __DIR__ . '/../config/runtimes.php');
|
||||
Config::load('runtimes-v2', __DIR__ . '/../config/runtimes-v2.php');
|
||||
Config::load('usage', __DIR__ . '/../config/usage.php');
|
||||
Config::load('roles', __DIR__ . '/../config/roles.php'); // User roles and scopes
|
||||
Config::load('scopes', __DIR__ . '/../config/scopes.php'); // User roles and scopes
|
||||
Config::load('services', __DIR__ . '/../config/services.php'); // List of services
|
||||
Config::load('variables', __DIR__ . '/../config/variables.php'); // List of env variables
|
||||
Config::load('regions', __DIR__ . '/../config/regions.php'); // List of available regions
|
||||
Config::load('avatar-browsers', __DIR__ . '/../config/avatars/browsers.php');
|
||||
Config::load('avatar-credit-cards', __DIR__ . '/../config/avatars/credit-cards.php');
|
||||
Config::load('avatar-flags', __DIR__ . '/../config/avatars/flags.php');
|
||||
Config::load('locale-codes', __DIR__ . '/../config/locale/codes.php');
|
||||
Config::load('locale-currencies', __DIR__ . '/../config/locale/currencies.php');
|
||||
Config::load('locale-eu', __DIR__ . '/../config/locale/eu.php');
|
||||
Config::load('locale-languages', __DIR__ . '/../config/locale/languages.php');
|
||||
Config::load('locale-phones', __DIR__ . '/../config/locale/phones.php');
|
||||
Config::load('locale-countries', __DIR__ . '/../config/locale/countries.php');
|
||||
Config::load('locale-continents', __DIR__ . '/../config/locale/continents.php');
|
||||
Config::load('locale-templates', __DIR__ . '/../config/locale/templates.php');
|
||||
Config::load('storage-logos', __DIR__ . '/../config/storage/logos.php');
|
||||
Config::load('storage-mimes', __DIR__ . '/../config/storage/mimes.php');
|
||||
Config::load('storage-inputs', __DIR__ . '/../config/storage/inputs.php');
|
||||
Config::load('storage-outputs', __DIR__ . '/../config/storage/outputs.php');
|
||||
Config::load('specifications', __DIR__ . '/../config/specifications.php');
|
||||
Config::load('templates-function', __DIR__ . '/../config/templates/function.php');
|
||||
Config::load('templates-site', __DIR__ . '/../config/templates/site.php');
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Platform\Modules\Compute\Specification;
|
||||
|
||||
const APP_NAME = 'Appwrite';
|
||||
const APP_DOMAIN = 'appwrite.io';
|
||||
const APP_EMAIL_TEAM = 'team@localhost.test'; // Default email address
|
||||
const APP_EMAIL_SECURITY = ''; // Default security email address
|
||||
const APP_USERAGENT = APP_NAME . '-Server v%s. Please report abuse at %s';
|
||||
const APP_MODE_DEFAULT = 'default';
|
||||
const APP_MODE_ADMIN = 'admin';
|
||||
const APP_PAGING_LIMIT = 12;
|
||||
const APP_LIMIT_COUNT = 5000;
|
||||
const APP_LIMIT_USERS = 10_000;
|
||||
const APP_LIMIT_USER_PASSWORD_HISTORY = 20;
|
||||
const APP_LIMIT_USER_SESSIONS_MAX = 100;
|
||||
const APP_LIMIT_USER_SESSIONS_DEFAULT = 10;
|
||||
const APP_LIMIT_ANTIVIRUS = 20_000_000; //20MB
|
||||
const APP_LIMIT_ENCRYPTION = 20_000_000; //20MB
|
||||
const APP_LIMIT_COMPRESSION = 20_000_000; //20MB
|
||||
const APP_LIMIT_ARRAY_PARAMS_SIZE = 100; // Default maximum of how many elements can there be in API parameter that expects array value
|
||||
const APP_LIMIT_ARRAY_LABELS_SIZE = 1000; // Default maximum of how many labels elements can there be in API parameter that expects array value
|
||||
const APP_LIMIT_ARRAY_ELEMENT_SIZE = 4096; // Default maximum length of element in array parameter represented by maximum URL length.
|
||||
const APP_LIMIT_SUBQUERY = 1000;
|
||||
const APP_LIMIT_SUBSCRIBERS_SUBQUERY = 1_000_000;
|
||||
const APP_LIMIT_WRITE_RATE_DEFAULT = 60; // Default maximum write rate per rate period
|
||||
const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate period in seconds
|
||||
const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return in list API calls
|
||||
const APP_KEY_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_USER_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_PROJECT_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_BUSTER = 4318;
|
||||
const APP_VERSION_STABLE = '1.7.0';
|
||||
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
|
||||
const APP_DATABASE_ATTRIBUTE_DATETIME = 'datetime';
|
||||
const APP_DATABASE_ATTRIBUTE_URL = 'url';
|
||||
const APP_DATABASE_ATTRIBUTE_INT_RANGE = 'intRange';
|
||||
const APP_DATABASE_ATTRIBUTE_FLOAT_RANGE = 'floatRange';
|
||||
const APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH = 1_073_741_824; // 2^32 bits / 4 bits per char
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_API = 15 * 1000; // 15 seconds
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER = 300 * 1000; // 5 minutes
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_TASK = 300 * 1000; // 5 minutes
|
||||
const APP_DATABASE_QUERY_MAX_VALUES = 500;
|
||||
const APP_STORAGE_UPLOADS = '/storage/uploads';
|
||||
const APP_STORAGE_SITES = '/storage/sites';
|
||||
const APP_STORAGE_FUNCTIONS = '/storage/functions';
|
||||
const APP_STORAGE_BUILDS = '/storage/builds';
|
||||
const APP_STORAGE_CACHE = '/storage/cache';
|
||||
const APP_STORAGE_CERTIFICATES = '/storage/certificates';
|
||||
const APP_STORAGE_CONFIG = '/storage/config';
|
||||
const APP_STORAGE_READ_BUFFER = 20 * (1000 * 1000); //20MB other names `APP_STORAGE_MEMORY_LIMIT`, `APP_STORAGE_MEMORY_BUFFER`, `APP_STORAGE_READ_LIMIT`, `APP_STORAGE_BUFFER_LIMIT`
|
||||
const APP_SOCIAL_TWITTER = 'https://twitter.com/appwrite';
|
||||
const APP_SOCIAL_TWITTER_HANDLE = 'appwrite';
|
||||
const APP_SOCIAL_FACEBOOK = 'https://www.facebook.com/appwrite.io';
|
||||
const APP_SOCIAL_LINKEDIN = 'https://www.linkedin.com/company/appwrite';
|
||||
const APP_SOCIAL_INSTAGRAM = 'https://www.instagram.com/appwrite.io';
|
||||
const APP_SOCIAL_GITHUB = 'https://github.com/appwrite';
|
||||
const APP_SOCIAL_DISCORD = 'https://appwrite.io/discord';
|
||||
const APP_SOCIAL_DISCORD_CHANNEL = '564160730845151244';
|
||||
const APP_SOCIAL_DEV = 'https://dev.to/appwrite';
|
||||
const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite';
|
||||
const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1';
|
||||
const APP_HOSTNAME_INTERNAL = 'appwrite';
|
||||
const APP_COMPUTE_CPUS_DEFAULT = 0.5;
|
||||
const APP_COMPUTE_MEMORY_DEFAULT = 512;
|
||||
const APP_COMPUTE_SPECIFICATION_DEFAULT = Specification::S_1VCPU_512MB;
|
||||
const APP_PLATFORM_SERVER = 'server';
|
||||
const APP_PLATFORM_CLIENT = 'client';
|
||||
const APP_PLATFORM_CONSOLE = 'console';
|
||||
|
||||
// Database Reconnect
|
||||
const DATABASE_RECONNECT_SLEEP = 2;
|
||||
const DATABASE_RECONNECT_MAX_ATTEMPTS = 10;
|
||||
|
||||
// Database Worker Types
|
||||
const DATABASE_TYPE_CREATE_ATTRIBUTE = 'createAttribute';
|
||||
const DATABASE_TYPE_CREATE_INDEX = 'createIndex';
|
||||
const DATABASE_TYPE_DELETE_ATTRIBUTE = 'deleteAttribute';
|
||||
const DATABASE_TYPE_DELETE_INDEX = 'deleteIndex';
|
||||
const DATABASE_TYPE_DELETE_COLLECTION = 'deleteCollection';
|
||||
const DATABASE_TYPE_DELETE_DATABASE = 'deleteDatabase';
|
||||
|
||||
// Build Worker Types
|
||||
const BUILD_TYPE_DEPLOYMENT = 'deployment';
|
||||
const BUILD_TYPE_RETRY = 'retry';
|
||||
|
||||
// Deletion Types
|
||||
const DELETE_TYPE_DATABASES = 'databases';
|
||||
const DELETE_TYPE_DOCUMENT = 'document';
|
||||
const DELETE_TYPE_COLLECTIONS = 'collections';
|
||||
const DELETE_TYPE_PROJECTS = 'projects';
|
||||
const DELETE_TYPE_SITES = 'sites';
|
||||
const DELETE_TYPE_FUNCTIONS = 'functions';
|
||||
const DELETE_TYPE_DEPLOYMENTS = 'deployments';
|
||||
const DELETE_TYPE_USERS = 'users';
|
||||
const DELETE_TYPE_TEAM_PROJECTS = 'teams_projects';
|
||||
const DELETE_TYPE_EXECUTIONS = 'executions';
|
||||
const DELETE_TYPE_AUDIT = 'audit';
|
||||
const DELETE_TYPE_ABUSE = 'abuse';
|
||||
const DELETE_TYPE_USAGE = 'usage';
|
||||
const DELETE_TYPE_REALTIME = 'realtime';
|
||||
const DELETE_TYPE_BUCKETS = 'buckets';
|
||||
const DELETE_TYPE_INSTALLATIONS = 'installations';
|
||||
const DELETE_TYPE_RULES = 'rules';
|
||||
const DELETE_TYPE_SESSIONS = 'sessions';
|
||||
const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp';
|
||||
const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource';
|
||||
const DELETE_TYPE_SCHEDULES = 'schedules';
|
||||
const DELETE_TYPE_TOPIC = 'topic';
|
||||
const DELETE_TYPE_TARGET = 'target';
|
||||
const DELETE_TYPE_EXPIRED_TARGETS = 'invalid_targets';
|
||||
const DELETE_TYPE_SESSION_TARGETS = 'session_targets';
|
||||
const DELETE_TYPE_MAINTENANCE = 'maintenance';
|
||||
|
||||
// Message types
|
||||
const MESSAGE_SEND_TYPE_INTERNAL = 'internal';
|
||||
const MESSAGE_SEND_TYPE_EXTERNAL = 'external';
|
||||
// Mail Types
|
||||
const MAIL_TYPE_VERIFICATION = 'verification';
|
||||
const MAIL_TYPE_MAGIC_SESSION = 'magicSession';
|
||||
const MAIL_TYPE_RECOVERY = 'recovery';
|
||||
const MAIL_TYPE_INVITATION = 'invitation';
|
||||
const MAIL_TYPE_CERTIFICATE = 'certificate';
|
||||
// Auth Types
|
||||
const APP_AUTH_TYPE_SESSION = 'Session';
|
||||
const APP_AUTH_TYPE_JWT = 'JWT';
|
||||
const APP_AUTH_TYPE_KEY = 'Key';
|
||||
const APP_AUTH_TYPE_ADMIN = 'Admin';
|
||||
// Response related
|
||||
const MAX_OUTPUT_CHUNK_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
// Function headers
|
||||
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host'];
|
||||
const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length'];
|
||||
// Message types
|
||||
const MESSAGE_TYPE_EMAIL = 'email';
|
||||
const MESSAGE_TYPE_SMS = 'sms';
|
||||
const MESSAGE_TYPE_PUSH = 'push';
|
||||
// API key types
|
||||
const API_KEY_STANDARD = 'standard';
|
||||
const API_KEY_DYNAMIC = 'dynamic';
|
||||
// Usage metrics
|
||||
const METRIC_TEAMS = 'teams';
|
||||
const METRIC_USERS = 'users';
|
||||
const METRIC_WEBHOOKS_SENT = 'webhooks.events.sent';
|
||||
const METRIC_WEBHOOKS_FAILED = 'webhooks.events.failed';
|
||||
const METRIC_WEBHOOK_ID_SENT = '{webhookInternalId}.webhooks.events.sent';
|
||||
const METRIC_WEBHOOK_ID_FAILED = '{webhookInternalId}.webhooks.events.failed';
|
||||
const METRIC_AUTH_METHOD_PHONE = 'auth.method.phone';
|
||||
const METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE = METRIC_AUTH_METHOD_PHONE . '.{countryCode}';
|
||||
const METRIC_MESSAGES = 'messages';
|
||||
const METRIC_MESSAGES_SENT = METRIC_MESSAGES . '.sent';
|
||||
const METRIC_MESSAGES_FAILED = METRIC_MESSAGES . '.failed';
|
||||
const METRIC_MESSAGES_TYPE = METRIC_MESSAGES . '.{type}';
|
||||
const METRIC_MESSAGES_TYPE_SENT = METRIC_MESSAGES . '.{type}.sent';
|
||||
const METRIC_MESSAGES_TYPE_FAILED = METRIC_MESSAGES . '.{type}.failed';
|
||||
const METRIC_MESSAGES_TYPE_PROVIDER = METRIC_MESSAGES . '.{type}.{provider}';
|
||||
const METRIC_MESSAGES_TYPE_PROVIDER_SENT = METRIC_MESSAGES . '.{type}.{provider}.sent';
|
||||
const METRIC_MESSAGES_TYPE_PROVIDER_FAILED = METRIC_MESSAGES . '.{type}.{provider}.failed';
|
||||
const METRIC_SESSIONS = 'sessions';
|
||||
const METRIC_DATABASES = 'databases';
|
||||
const METRIC_COLLECTIONS = 'collections';
|
||||
const METRIC_DATABASES_STORAGE = 'databases.storage';
|
||||
const METRIC_DATABASE_ID_COLLECTIONS = '{databaseInternalId}.collections';
|
||||
const METRIC_DATABASE_ID_STORAGE = '{databaseInternalId}.databases.storage';
|
||||
const METRIC_DOCUMENTS = 'documents';
|
||||
const METRIC_DATABASE_ID_DOCUMENTS = '{databaseInternalId}.documents';
|
||||
const METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS = '{databaseInternalId}.{collectionInternalId}.documents';
|
||||
const METRIC_DATABASE_ID_COLLECTION_ID_STORAGE = '{databaseInternalId}.{collectionInternalId}.databases.storage';
|
||||
const METRIC_DATABASES_OPERATIONS_READS = 'databases.operations.reads';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_READS = '{databaseInternalId}.databases.operations.reads';
|
||||
const METRIC_DATABASES_OPERATIONS_WRITES = 'databases.operations.writes';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_WRITES = '{databaseInternalId}.databases.operations.writes';
|
||||
const METRIC_BUCKETS = 'buckets';
|
||||
const METRIC_FILES = 'files';
|
||||
const METRIC_FILES_STORAGE = 'files.storage';
|
||||
const METRIC_FILES_TRANSFORMATIONS = 'files.transformations';
|
||||
const METRIC_BUCKET_ID_FILES_TRANSFORMATIONS = '{bucketInternalId}.files.transformations';
|
||||
const METRIC_FILES_IMAGES_TRANSFORMED = 'files.imagesTransformed';
|
||||
const METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED = '{bucketInternalId}.files.imagesTransformed';
|
||||
const METRIC_BUCKET_ID_FILES = '{bucketInternalId}.files';
|
||||
const METRIC_BUCKET_ID_FILES_STORAGE = '{bucketInternalId}.files.storage';
|
||||
const METRIC_SITES = 'sites';
|
||||
const METRIC_FUNCTIONS = 'functions';
|
||||
const METRIC_DEPLOYMENTS = 'deployments';
|
||||
const METRIC_DEPLOYMENTS_STORAGE = 'deployments.storage';
|
||||
const METRIC_BUILDS = 'builds';
|
||||
const METRIC_BUILDS_SUCCESS = 'builds.success';
|
||||
const METRIC_BUILDS_FAILED = 'builds.failed';
|
||||
const METRIC_BUILDS_STORAGE = 'builds.storage';
|
||||
const METRIC_BUILDS_COMPUTE = 'builds.compute';
|
||||
const METRIC_BUILDS_COMPUTE_SUCCESS = 'builds.compute.success';
|
||||
const METRIC_BUILDS_COMPUTE_FAILED = 'builds.compute.failed';
|
||||
const METRIC_BUILDS_MB_SECONDS = 'builds.mbSeconds';
|
||||
const METRIC_FUNCTION_ID_BUILDS = '{functionInternalId}.builds';
|
||||
const METRIC_FUNCTION_ID_BUILDS_SUCCESS = '{functionInternalId}.builds.success';
|
||||
const METRIC_FUNCTION_ID_BUILDS_FAILED = '{functionInternalId}.builds.failed';
|
||||
const METRIC_FUNCTION_ID_BUILDS_STORAGE = '{functionInternalId}.builds.storage';
|
||||
const METRIC_FUNCTION_ID_BUILDS_COMPUTE = '{functionInternalId}.builds.compute';
|
||||
const METRIC_FUNCTION_ID_BUILDS_COMPUTE_SUCCESS = '{functionInternalId}.builds.compute.success';
|
||||
const METRIC_FUNCTION_ID_BUILDS_COMPUTE_FAILED = '{functionInternalId}.builds.compute.failed';
|
||||
const METRIC_FUNCTION_ID_BUILDS_MB_SECONDS = '{functionInternalId}.builds.mbSeconds';
|
||||
const METRIC_SITES_ID_BUILDS = 'sites.{siteInternalId}.builds';
|
||||
const METRIC_SITES_ID_BUILDS_SUCCESS = 'sites.{siteInternalId}.builds.success';
|
||||
const METRIC_SITES_ID_BUILDS_FAILED = 'sites.{siteInternalId}.builds.failed';
|
||||
const METRIC_SITES_ID_BUILDS_STORAGE = 'sites.{siteInternalId}.builds.storage';
|
||||
const METRIC_SITES_ID_BUILDS_COMPUTE = 'sites.{siteInternalId}.builds.compute';
|
||||
const METRIC_SITES_ID_BUILDS_COMPUTE_SUCCESS = 'sites.{siteInternalId}.builds.compute.success';
|
||||
const METRIC_SITES_ID_BUILDS_COMPUTE_FAILED = 'sites.{siteInternalId}.builds.compute.failed';
|
||||
const METRIC_SITES_ID_BUILDS_MB_SECONDS = 'sites.{siteInternalId}.builds.mbSeconds';
|
||||
const METRIC_FUNCTION_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
|
||||
const METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
|
||||
const METRIC_EXECUTIONS = 'executions';
|
||||
const METRIC_EXECUTIONS_COMPUTE = 'executions.compute';
|
||||
const METRIC_EXECUTIONS_MB_SECONDS = 'executions.mbSeconds';
|
||||
const METRIC_FUNCTION_ID_EXECUTIONS = '{functionInternalId}.executions';
|
||||
const METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE = '{functionInternalId}.executions.compute';
|
||||
const METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS = '{functionInternalId}.executions.mbSeconds';
|
||||
const METRIC_SITE_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
|
||||
const METRIC_SITE_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
|
||||
const METRIC_SITE_ID_BUILDS = '{siteInternalId}.builds';
|
||||
const METRIC_SITE_ID_BUILDS_STORAGE = '{siteInternalId}.builds.storage';
|
||||
const METRIC_SITE_ID_BUILDS_COMPUTE = '{siteInternalId}.builds.compute';
|
||||
const METRIC_SITE_ID_BUILDS_MB_SECONDS = '{siteInternalId}.builds.mbSeconds';
|
||||
const METRIC_NETWORK_REQUESTS = 'network.requests';
|
||||
const METRIC_NETWORK_INBOUND = 'network.inbound';
|
||||
const METRIC_NETWORK_OUTBOUND = 'network.outbound';
|
||||
const METRIC_MAU = 'users.mau';
|
||||
const METRIC_DAU = 'users.dau';
|
||||
const METRIC_WAU = 'users.wau';
|
||||
const METRIC_WEBHOOKS = 'webhooks';
|
||||
const METRIC_PLATFORMS = 'platforms';
|
||||
const METRIC_PROVIDERS = 'providers';
|
||||
const METRIC_TOPICS = 'topics';
|
||||
const METRIC_TARGETS = 'targets';
|
||||
const METRIC_PROVIDER_TYPE_TARGETS = '{providerType}.targets';
|
||||
const METRIC_KEYS = 'keys';
|
||||
const METRIC_DOMAINS = 'domains';
|
||||
const METRIC_RESOURCE_TYPE_ID_BUILDS = '{resourceType}.{resourceInternalId}.builds';
|
||||
const METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE = '{resourceType}.{resourceInternalId}.builds.storage';
|
||||
const METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
|
||||
const METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
|
||||
|
||||
// Resource types
|
||||
|
||||
const RESOURCE_TYPE_PROJECTS = 'projects';
|
||||
const RESOURCE_TYPE_FUNCTIONS = 'functions';
|
||||
const RESOURCE_TYPE_SITES = 'sites';
|
||||
const RESOURCE_TYPE_DATABASES = 'databases';
|
||||
const RESOURCE_TYPE_BUCKETS = 'buckets';
|
||||
const RESOURCE_TYPE_PROVIDERS = 'providers';
|
||||
const RESOURCE_TYPE_TOPICS = 'topics';
|
||||
const RESOURCE_TYPE_SUBSCRIBERS = 'subscribers';
|
||||
const RESOURCE_TYPE_MESSAGES = 'messages';
|
||||
@@ -0,0 +1,404 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\System\System;
|
||||
|
||||
Database::addFilter(
|
||||
'casting',
|
||||
function (mixed $value) {
|
||||
return json_encode(['value' => $value], JSON_PRESERVE_ZERO_FRACTION);
|
||||
},
|
||||
function (mixed $value) {
|
||||
if (is_null($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return json_decode($value, true)['value'];
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'enum',
|
||||
function (mixed $value, Document $attribute) {
|
||||
if ($attribute->isSet('elements')) {
|
||||
$attribute->removeAttribute('elements');
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
function (mixed $value, Document $attribute) {
|
||||
$formatOptions = \json_decode($attribute->getAttribute('formatOptions', '[]'), true);
|
||||
if (isset($formatOptions['elements'])) {
|
||||
$attribute->setAttribute('elements', $formatOptions['elements']);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'range',
|
||||
function (mixed $value, Document $attribute) {
|
||||
if ($attribute->isSet('min')) {
|
||||
$attribute->removeAttribute('min');
|
||||
}
|
||||
if ($attribute->isSet('max')) {
|
||||
$attribute->removeAttribute('max');
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
function (mixed $value, Document $attribute) {
|
||||
$formatOptions = json_decode($attribute->getAttribute('formatOptions', '[]'), true);
|
||||
if (isset($formatOptions['min']) || isset($formatOptions['max'])) {
|
||||
$attribute
|
||||
->setAttribute('min', $formatOptions['min'])
|
||||
->setAttribute('max', $formatOptions['max']);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryAttributes',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
$attributes = $database->find('attributes', [
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getLimitForAttributes()),
|
||||
]);
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) {
|
||||
$options = $attribute->getAttribute('options');
|
||||
foreach ($options as $key => $value) {
|
||||
$attribute->setAttribute($key, $value);
|
||||
}
|
||||
$attribute->removeAttribute('options');
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryIndexes',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('indexes', [
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getLimitForIndexes()),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryPlatforms',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('platforms', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryKeys',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('keys', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryWebhooks',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('webhooks', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQuerySessions',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database->find('sessions', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryTokens',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('tokens', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryChallenges',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('challenges', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryAuthenticators',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('authenticators', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryMemberships',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('memberships', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryVariables',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('variables', [
|
||||
Query::equal('resourceInternalId', [$document->getInternalId()]),
|
||||
Query::equal('resourceType', ['function', 'site']),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'encrypt',
|
||||
function (mixed $value) {
|
||||
$key = System::getEnv('_APP_OPENSSL_KEY_V1');
|
||||
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
|
||||
$tag = null;
|
||||
|
||||
return json_encode([
|
||||
'data' => OpenSSL::encrypt($value, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag),
|
||||
'method' => OpenSSL::CIPHER_AES_128_GCM,
|
||||
'iv' => \bin2hex($iv),
|
||||
'tag' => \bin2hex($tag ?? ''),
|
||||
'version' => '1',
|
||||
]);
|
||||
},
|
||||
function (mixed $value) {
|
||||
if (is_null($value)) {
|
||||
return;
|
||||
}
|
||||
$value = json_decode($value, true);
|
||||
$key = System::getEnv('_APP_OPENSSL_KEY_V' . $value['version']);
|
||||
|
||||
return OpenSSL::decrypt($value['data'], $value['method'], $key, 0, hex2bin($value['iv']), hex2bin($value['tag']));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryProjectVariables',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('variables', [
|
||||
Query::equal('resourceType', ['project']),
|
||||
Query::limit(APP_LIMIT_SUBQUERY)
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'userSearch',
|
||||
function (mixed $value, Document $user) {
|
||||
$searchValues = [
|
||||
$user->getId(),
|
||||
$user->getAttribute('email', ''),
|
||||
$user->getAttribute('name', ''),
|
||||
$user->getAttribute('phone', '')
|
||||
];
|
||||
|
||||
foreach ($user->getAttribute('labels', []) as $label) {
|
||||
$searchValues[] = 'label:' . $label;
|
||||
}
|
||||
|
||||
$search = implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryTargets',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('targets', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY)
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryTopicTargets',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
$targetIds = Authorization::skip(fn () => \array_map(
|
||||
fn ($document) => $document->getAttribute('targetInternalId'),
|
||||
$database->find('subscribers', [
|
||||
Query::equal('topicInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBSCRIBERS_SUBQUERY)
|
||||
])
|
||||
));
|
||||
if (\count($targetIds) > 0) {
|
||||
return $database->skipValidation(fn () => $database->find('targets', [
|
||||
Query::equal('$internalId', $targetIds)
|
||||
]));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'providerSearch',
|
||||
function (mixed $value, Document $provider) {
|
||||
$searchValues = [
|
||||
$provider->getId(),
|
||||
$provider->getAttribute('name', ''),
|
||||
$provider->getAttribute('provider', ''),
|
||||
$provider->getAttribute('type', '')
|
||||
];
|
||||
|
||||
$search = \implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'topicSearch',
|
||||
function (mixed $value, Document $topic) {
|
||||
$searchValues = [
|
||||
$topic->getId(),
|
||||
$topic->getAttribute('name', ''),
|
||||
$topic->getAttribute('description', ''),
|
||||
];
|
||||
|
||||
$search = \implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'messageSearch',
|
||||
function (mixed $value, Document $message) {
|
||||
$searchValues = [
|
||||
$message->getId(),
|
||||
$message->getAttribute('description', ''),
|
||||
$message->getAttribute('status', ''),
|
||||
];
|
||||
|
||||
$data = \json_decode($message->getAttribute('data', []), true);
|
||||
$providerType = $message->getAttribute('providerType', '');
|
||||
|
||||
switch ($providerType) {
|
||||
case MESSAGE_TYPE_EMAIL:
|
||||
$searchValues[] = $data['subject'];
|
||||
$searchValues[] = MESSAGE_TYPE_EMAIL;
|
||||
break;
|
||||
case MESSAGE_TYPE_SMS:
|
||||
$searchValues[] = $data['content'];
|
||||
$searchValues[] = MESSAGE_TYPE_SMS;
|
||||
break;
|
||||
case MESSAGE_TYPE_PUSH:
|
||||
$searchValues[] = $data['title'] ?? '';
|
||||
$searchValues[] = MESSAGE_TYPE_PUSH;
|
||||
break;
|
||||
}
|
||||
|
||||
$search = \implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
use Utopia\Database\Validator\Structure;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_EMAIL, function () {
|
||||
return new Email();
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_DATETIME, function () {
|
||||
return new DatetimeValidator();
|
||||
}, Database::VAR_DATETIME);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_ENUM, function ($attribute) {
|
||||
$elements = $attribute['formatOptions']['elements'] ?? [];
|
||||
return new WhiteList($elements, true);
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_IP, function () {
|
||||
return new IP();
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_URL, function () {
|
||||
return new URL();
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_INT_RANGE, function ($attribute) {
|
||||
$min = $attribute['formatOptions']['min'] ?? -INF;
|
||||
$max = $attribute['formatOptions']['max'] ?? INF;
|
||||
return new Range($min, $max, Range::TYPE_INTEGER);
|
||||
}, Database::VAR_INTEGER);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_FLOAT_RANGE, function ($attribute) {
|
||||
$min = $attribute['formatOptions']['min'] ?? -INF;
|
||||
$max = $attribute['formatOptions']['max'] ?? INF;
|
||||
return new Range($min, $max, Range::TYPE_FLOAT);
|
||||
}, Database::VAR_FLOAT);
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Locale\Locale;
|
||||
|
||||
Locale::$exceptions = false;
|
||||
|
||||
$locales = Config::getParam('locale-codes', []);
|
||||
|
||||
foreach ($locales as $locale) {
|
||||
$code = $locale['code'];
|
||||
|
||||
$path = __DIR__ . '/../config/locale/translations/' . $code . '.json';
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
$path = __DIR__ . '/../config/locale/translations/' . \substr($code, 0, 2) . '.json'; // if `ar-ae` doesn't exist, look for `ar`
|
||||
if (!\file_exists($path)) {
|
||||
$path = __DIR__ . '/../config/locale/translations/en.json'; // if none translation exists, use default from `en.json`
|
||||
}
|
||||
}
|
||||
|
||||
Locale::setLanguageFromJSON($code, $path);
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\GraphQL\Promises\Adapter\Swoole;
|
||||
use Appwrite\Hooks\Hooks;
|
||||
use Appwrite\PubSub\Adapter\Redis as PubSub;
|
||||
use Appwrite\URL\URL as AppwriteURL;
|
||||
use MaxMind\Db\Reader;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Swoole\Database\PDOProxy;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Redis as RedisCache;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Adapter\MariaDB;
|
||||
use Utopia\Database\Adapter\MySQL;
|
||||
use Utopia\Database\Adapter\SQL;
|
||||
use Utopia\Domains\Validator\PublicDomain;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Logger\Adapter\AppSignal;
|
||||
use Utopia\Logger\Adapter\LogOwl;
|
||||
use Utopia\Logger\Adapter\Raygun;
|
||||
use Utopia\Logger\Adapter\Sentry;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\Pools\Pool;
|
||||
use Utopia\Queue;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\System\System;
|
||||
|
||||
$register = new Registry();
|
||||
|
||||
App::setMode(System::getEnv('_APP_ENV', App::MODE_TYPE_PRODUCTION));
|
||||
|
||||
if (!App::isProduction()) {
|
||||
// Allow specific domains to skip public domain validation in dev environment
|
||||
// Useful for existing tests involving webhooks
|
||||
PublicDomain::allow(['request-catcher']);
|
||||
}
|
||||
$register->set('logger', function () {
|
||||
// Register error logger
|
||||
$providerName = System::getEnv('_APP_LOGGING_PROVIDER', '');
|
||||
$providerConfig = System::getEnv('_APP_LOGGING_CONFIG', '');
|
||||
|
||||
if (empty($providerConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$loggingProvider = new DSN($providerConfig ?? '');
|
||||
|
||||
$providerName = $loggingProvider->getScheme();
|
||||
$providerConfig = match ($providerName) {
|
||||
'sentry' => ['key' => $loggingProvider->getPassword(), 'projectId' => $loggingProvider->getUser() ?? '', 'host' => 'https://' . $loggingProvider->getHost()],
|
||||
'logowl' => ['ticket' => $loggingProvider->getUser() ?? '', 'host' => $loggingProvider->getHost()],
|
||||
default => ['key' => $loggingProvider->getHost()],
|
||||
};
|
||||
} catch (Throwable $th) {
|
||||
// Fallback for older Appwrite versions up to 1.5.x that use _APP_LOGGING_PROVIDER and _APP_LOGGING_CONFIG environment variables
|
||||
Console::warning('Using deprecated logging configuration. Please update your configuration to use DSN format.' . $th->getMessage());
|
||||
$configChunks = \explode(";", $providerConfig);
|
||||
|
||||
$providerConfig = match ($providerName) {
|
||||
'sentry' => [ 'key' => $configChunks[0], 'projectId' => $configChunks[1] ?? '', 'host' => '',],
|
||||
'logowl' => ['ticket' => $configChunks[0] ?? '', 'host' => ''],
|
||||
default => ['key' => $providerConfig],
|
||||
};
|
||||
}
|
||||
|
||||
if (empty($providerName) || empty($providerConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Logger::hasProvider($providerName)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Logging provider not supported. Logging is disabled");
|
||||
}
|
||||
|
||||
try {
|
||||
$adapter = match ($providerName) {
|
||||
'sentry' => new Sentry($providerConfig['projectId'], $providerConfig['key'], $providerConfig['host']),
|
||||
'logowl' => new LogOwl($providerConfig['ticket'], $providerConfig['host']),
|
||||
'raygun' => new Raygun($providerConfig['key']),
|
||||
'appsignal' => new AppSignal($providerConfig['key']),
|
||||
default => null
|
||||
};
|
||||
} catch (Throwable $th) {
|
||||
$adapter = null;
|
||||
}
|
||||
|
||||
if ($adapter === null) {
|
||||
Console::error("Logging provider not supported. Logging is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
return new Logger($adapter);
|
||||
});
|
||||
|
||||
$register->set('pools', function () {
|
||||
$group = new Group();
|
||||
|
||||
$fallbackForDB = 'db_main=' . AppwriteURL::unparse([
|
||||
'scheme' => 'mariadb',
|
||||
'host' => System::getEnv('_APP_DB_HOST', 'mariadb'),
|
||||
'port' => System::getEnv('_APP_DB_PORT', '3306'),
|
||||
'user' => System::getEnv('_APP_DB_USER', ''),
|
||||
'pass' => System::getEnv('_APP_DB_PASS', ''),
|
||||
'path' => System::getEnv('_APP_DB_SCHEMA', ''),
|
||||
]);
|
||||
$fallbackForRedis = 'redis_main=' . AppwriteURL::unparse([
|
||||
'scheme' => 'redis',
|
||||
'host' => System::getEnv('_APP_REDIS_HOST', 'redis'),
|
||||
'port' => System::getEnv('_APP_REDIS_PORT', '6379'),
|
||||
'user' => System::getEnv('_APP_REDIS_USER', ''),
|
||||
'pass' => System::getEnv('_APP_REDIS_PASS', ''),
|
||||
]);
|
||||
|
||||
$connections = [
|
||||
'console' => [
|
||||
'type' => 'database',
|
||||
'dsns' => $fallbackForDB,
|
||||
'multiple' => false,
|
||||
'schemes' => ['mariadb', 'mysql'],
|
||||
],
|
||||
'database' => [
|
||||
'type' => 'database',
|
||||
'dsns' => $fallbackForDB,
|
||||
'multiple' => true,
|
||||
'schemes' => ['mariadb', 'mysql'],
|
||||
],
|
||||
'logs' => [
|
||||
'type' => 'database',
|
||||
'dsns' => System::getEnv('_APP_CONNECTIONS_DB_LOGS', $fallbackForDB),
|
||||
'multiple' => false,
|
||||
'schemes' => ['mariadb', 'mysql'],
|
||||
],
|
||||
'publisher' => [
|
||||
'type' => 'publisher',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => false,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
'consumer' => [
|
||||
'type' => 'consumer',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => false,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
'pubsub' => [
|
||||
'type' => 'pubsub',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => false,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
'cache' => [
|
||||
'type' => 'cache',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => true,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
];
|
||||
|
||||
$maxConnections = System::getEnv('_APP_CONNECTIONS_MAX', 151);
|
||||
$instanceConnections = $maxConnections / System::getEnv('_APP_POOL_CLIENTS', 14);
|
||||
|
||||
$multiprocessing = System::getEnv('_APP_SERVER_MULTIPROCESS', 'disabled') === 'enabled';
|
||||
|
||||
if ($multiprocessing) {
|
||||
$workerCount = intval(System::getEnv('_APP_CPU_NUM', swoole_cpu_num())) * intval(System::getEnv('_APP_WORKER_PER_CORE', 6));
|
||||
} else {
|
||||
$workerCount = 1;
|
||||
}
|
||||
|
||||
if ($workerCount > $instanceConnections) {
|
||||
throw new \Exception('Pool size is too small. Increase the number of allowed database connections or decrease the number of workers.', 500);
|
||||
}
|
||||
|
||||
$poolSize = (int)($instanceConnections / $workerCount);
|
||||
|
||||
foreach ($connections as $key => $connection) {
|
||||
$type = $connection['type'] ?? '';
|
||||
$multiple = $connection['multiple'] ?? false;
|
||||
$schemes = $connection['schemes'] ?? [];
|
||||
$config = [];
|
||||
$dsns = explode(',', $connection['dsns'] ?? '');
|
||||
foreach ($dsns as &$dsn) {
|
||||
$dsn = explode('=', $dsn);
|
||||
$name = ($multiple) ? $key . '_' . $dsn[0] : $key;
|
||||
$dsn = $dsn[1] ?? '';
|
||||
$config[] = $name;
|
||||
if (empty($dsn)) {
|
||||
//throw new Exception(Exception::GENERAL_SERVER_ERROR, "Missing value for DSN connection in {$key}");
|
||||
continue;
|
||||
}
|
||||
|
||||
$dsn = new DSN($dsn);
|
||||
$dsnHost = $dsn->getHost();
|
||||
$dsnPort = $dsn->getPort();
|
||||
$dsnUser = $dsn->getUser();
|
||||
$dsnPass = $dsn->getPassword();
|
||||
$dsnScheme = $dsn->getScheme();
|
||||
$dsnDatabase = $dsn->getPath();
|
||||
|
||||
if (!in_array($dsnScheme, $schemes)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Invalid console database scheme");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Resource
|
||||
*
|
||||
* Creation could be reused across connection types like database, cache, queue, etc.
|
||||
*
|
||||
* Resource assignment to an adapter will happen below.
|
||||
*/
|
||||
$resource = match ($dsnScheme) {
|
||||
'mysql',
|
||||
'mariadb' => 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(
|
||||
PDO::ATTR_TIMEOUT => 3, // Seconds
|
||||
PDO::ATTR_PERSISTENT => false,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => true
|
||||
));
|
||||
});
|
||||
},
|
||||
'redis' => function () use ($dsnHost, $dsnPort, $dsnPass) {
|
||||
$redis = new \Redis();
|
||||
@$redis->pconnect($dsnHost, (int)$dsnPort);
|
||||
if ($dsnPass) {
|
||||
$redis->auth($dsnPass);
|
||||
}
|
||||
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
return $redis;
|
||||
},
|
||||
default => throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid scheme'),
|
||||
};
|
||||
|
||||
$pool = new Pool($name, $poolSize, function () use ($type, $resource, $dsn) {
|
||||
// Get Adapter
|
||||
switch ($type) {
|
||||
case 'database':
|
||||
$adapter = match ($dsn->getScheme()) {
|
||||
'mariadb' => new MariaDB($resource()),
|
||||
'mysql' => new MySQL($resource()),
|
||||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDatabase($dsn->getPath());
|
||||
return $adapter;
|
||||
case 'pubsub':
|
||||
return match ($dsn->getScheme()) {
|
||||
'redis' => new PubSub($resource()),
|
||||
default => null
|
||||
};
|
||||
case 'publisher':
|
||||
case 'consumer':
|
||||
return match ($dsn->getScheme()) {
|
||||
'redis' => new Queue\Broker\Redis(new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort())),
|
||||
default => null
|
||||
};
|
||||
case 'cache':
|
||||
return match ($dsn->getScheme()) {
|
||||
'redis' => new RedisCache($resource()),
|
||||
default => null
|
||||
};
|
||||
default:
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Server error: Missing adapter implementation.");
|
||||
}
|
||||
});
|
||||
|
||||
$group->add($pool);
|
||||
}
|
||||
|
||||
Config::setParam('pools-' . $key, $config);
|
||||
}
|
||||
|
||||
return $group;
|
||||
});
|
||||
|
||||
$register->set('db', function () {
|
||||
// This is usually for our workers or CLI commands scope
|
||||
$dbHost = System::getEnv('_APP_DB_HOST', '');
|
||||
$dbPort = System::getEnv('_APP_DB_PORT', '');
|
||||
$dbUser = System::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = System::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = System::getEnv('_APP_DB_SCHEMA', '');
|
||||
|
||||
return new PDO(
|
||||
"mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4",
|
||||
$dbUser,
|
||||
$dbPass,
|
||||
SQL::getPDOAttributes()
|
||||
);
|
||||
});
|
||||
|
||||
$register->set('smtp', function () {
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
$mail->isSMTP();
|
||||
|
||||
$username = System::getEnv('_APP_SMTP_USERNAME');
|
||||
$password = System::getEnv('_APP_SMTP_PASSWORD');
|
||||
|
||||
$mail->XMailer = 'Appwrite Mailer';
|
||||
$mail->Host = System::getEnv('_APP_SMTP_HOST', 'smtp');
|
||||
$mail->Port = System::getEnv('_APP_SMTP_PORT', 25);
|
||||
$mail->SMTPAuth = !empty($username) && !empty($password);
|
||||
$mail->Username = $username;
|
||||
$mail->Password = $password;
|
||||
$mail->SMTPSecure = System::getEnv('_APP_SMTP_SECURE', '');
|
||||
$mail->SMTPAutoTLS = false;
|
||||
$mail->CharSet = 'UTF-8';
|
||||
|
||||
$from = \urldecode(System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
|
||||
$email = System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
|
||||
|
||||
$mail->setFrom($email, $from);
|
||||
$mail->addReplyTo($email, $from);
|
||||
|
||||
$mail->isHTML(true);
|
||||
|
||||
return $mail;
|
||||
});
|
||||
$register->set('geodb', function () {
|
||||
return new Reader(__DIR__ . '/../assets/dbip/dbip-country-lite-2024-09.mmdb');
|
||||
});
|
||||
$register->set('passwordsDictionary', function () {
|
||||
$content = \file_get_contents(__DIR__ . '/../assets/security/10k-common-passwords');
|
||||
$content = explode("\n", $content);
|
||||
$content = array_flip($content);
|
||||
return $content;
|
||||
});
|
||||
$register->set('promiseAdapter', function () {
|
||||
return new Swoole();
|
||||
});
|
||||
$register->set('hooks', function () {
|
||||
return new Hooks();
|
||||
});
|
||||
@@ -0,0 +1,836 @@
|
||||
<?php
|
||||
|
||||
use Ahc\Jwt\JWT;
|
||||
use Ahc\Jwt\JWTException;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Auth\Key;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Migration;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\GraphQL\Schema;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Locale\Locale;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Storage\Device\Backblaze;
|
||||
use Utopia\Storage\Device\DOSpaces;
|
||||
use Utopia\Storage\Device\Linode;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Device\S3;
|
||||
use Utopia\Storage\Device\Wasabi;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Hostname;
|
||||
use Utopia\VCS\Adapter\Git\GitHub as VcsGitHub;
|
||||
|
||||
// Runtime Execution
|
||||
App::setResource('log', fn () => new Log());
|
||||
App::setResource('logger', function ($register) {
|
||||
return $register->get('logger');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('hooks', function ($register) {
|
||||
return $register->get('hooks');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('register', fn () => $register);
|
||||
App::setResource('locale', fn () => new Locale(System::getEnv('_APP_LOCALE', 'en')));
|
||||
|
||||
App::setResource('localeCodes', function () {
|
||||
return array_map(fn ($locale) => $locale['code'], Config::getParam('locale-codes', []));
|
||||
});
|
||||
|
||||
// Queues
|
||||
App::setResource('publisher', function (Group $pools) {
|
||||
return $pools->get('publisher')->pop()->getResource();
|
||||
}, ['pools']);
|
||||
App::setResource('consumer', function (Group $pools) {
|
||||
return $pools->get('consumer')->pop()->getResource();
|
||||
}, ['pools']);
|
||||
App::setResource('queueForMessaging', function (Publisher $publisher) {
|
||||
return new Messaging($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForMails', function (Publisher $publisher) {
|
||||
return new Mail($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForBuilds', function (Publisher $publisher) {
|
||||
return new Build($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForDatabase', function (Publisher $publisher) {
|
||||
return new EventDatabase($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForDeletes', function (Publisher $publisher) {
|
||||
return new Delete($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForEvents', function (Publisher $publisher) {
|
||||
return new Event($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForWebhooks', function (Publisher $publisher) {
|
||||
return new Webhook($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForRealtime', function () {
|
||||
return new Realtime();
|
||||
}, []);
|
||||
App::setResource('queueForStatsUsage', function (Publisher $publisher) {
|
||||
return new StatsUsage($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForAudits', function (Publisher $publisher) {
|
||||
return new Audit($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForFunctions', function (Publisher $publisher) {
|
||||
return new Func($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForCertificates', function (Publisher $publisher) {
|
||||
return new Certificate($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForMigrations', function (Publisher $publisher) {
|
||||
return new Migration($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('clients', function ($request, $console, $project) {
|
||||
$console->setAttribute('platforms', [ // Always allow current host
|
||||
'$collection' => ID::custom('platforms'),
|
||||
'name' => 'Current Host',
|
||||
'type' => Origin::CLIENT_TYPE_WEB,
|
||||
'hostname' => $request->getHostname(),
|
||||
], Document::SET_TYPE_APPEND);
|
||||
|
||||
$hostnames = explode(',', System::getEnv('_APP_CONSOLE_HOSTNAMES', ''));
|
||||
$validator = new Hostname();
|
||||
foreach ($hostnames as $hostname) {
|
||||
$hostname = trim($hostname);
|
||||
if (!$validator->isValid($hostname)) {
|
||||
continue;
|
||||
}
|
||||
$console->setAttribute('platforms', [
|
||||
'$collection' => ID::custom('platforms'),
|
||||
'type' => Origin::CLIENT_TYPE_WEB,
|
||||
'name' => $hostname,
|
||||
'hostname' => $hostname,
|
||||
], Document::SET_TYPE_APPEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All verified client URLs for both console and current projects
|
||||
* + Filter for duplicated entries
|
||||
*/
|
||||
$clientsConsole = \array_map(
|
||||
fn ($node) => $node['hostname'],
|
||||
\array_filter(
|
||||
$console->getAttribute('platforms', []),
|
||||
fn ($node) => (isset($node['type']) && ($node['type'] === Origin::CLIENT_TYPE_WEB) && !empty($node['hostname']))
|
||||
)
|
||||
);
|
||||
|
||||
$clients = $clientsConsole;
|
||||
$platforms = $project->getAttribute('platforms', []);
|
||||
|
||||
foreach ($platforms as $node) {
|
||||
if (
|
||||
isset($node['type']) &&
|
||||
($node['type'] === Origin::CLIENT_TYPE_WEB ||
|
||||
$node['type'] === Origin::CLIENT_TYPE_FLUTTER_WEB) &&
|
||||
!empty($node['hostname'])
|
||||
) {
|
||||
$clients[] = $node['hostname'];
|
||||
}
|
||||
}
|
||||
|
||||
return \array_unique($clients);
|
||||
}, ['request', 'console', 'project']);
|
||||
|
||||
App::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForPlatform) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
/** @var string $mode */
|
||||
|
||||
Authorization::setDefaultStatus(true);
|
||||
|
||||
Auth::setCookieName('a_session_' . $project->getId());
|
||||
|
||||
if (APP_MODE_ADMIN === $mode) {
|
||||
Auth::setCookieName('a_session_' . $console->getId());
|
||||
}
|
||||
|
||||
$session = Auth::decodeSession(
|
||||
$request->getCookie(
|
||||
Auth::$cookieName, // Get sessions
|
||||
$request->getCookie(Auth::$cookieName . '_legacy', '')
|
||||
)
|
||||
);
|
||||
|
||||
// Get session from header for SSR clients
|
||||
if (empty($session['id']) && empty($session['secret'])) {
|
||||
$sessionHeader = $request->getHeader('x-appwrite-session', '');
|
||||
|
||||
if (!empty($sessionHeader)) {
|
||||
$session = Auth::decodeSession($sessionHeader);
|
||||
}
|
||||
}
|
||||
|
||||
// Get fallback session from old clients (no SameSite support) or clients who block 3rd-party cookies
|
||||
if ($response) {
|
||||
$response->addHeader('X-Debug-Fallback', 'false');
|
||||
}
|
||||
|
||||
if (empty($session['id']) && empty($session['secret'])) {
|
||||
if ($response) {
|
||||
$response->addHeader('X-Debug-Fallback', 'true');
|
||||
}
|
||||
$fallback = $request->getHeader('x-fallback-cookies', '');
|
||||
$fallback = \json_decode($fallback, true);
|
||||
$session = Auth::decodeSession(((isset($fallback[Auth::$cookieName])) ? $fallback[Auth::$cookieName] : ''));
|
||||
}
|
||||
|
||||
Auth::$unique = $session['id'] ?? '';
|
||||
Auth::$secret = $session['secret'] ?? '';
|
||||
|
||||
if (APP_MODE_ADMIN !== $mode) {
|
||||
if ($project->isEmpty()) {
|
||||
$user = new Document([]);
|
||||
} else {
|
||||
if ($project->getId() === 'console') {
|
||||
$user = $dbForPlatform->getDocument('users', Auth::$unique);
|
||||
} else {
|
||||
$user = $dbForProject->getDocument('users', Auth::$unique);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$user = $dbForPlatform->getDocument('users', Auth::$unique);
|
||||
}
|
||||
|
||||
if (
|
||||
$user->isEmpty() // Check a document has been found in the DB
|
||||
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret)
|
||||
) { // Validate user has valid login token
|
||||
$user = new Document([]);
|
||||
}
|
||||
|
||||
// if (APP_MODE_ADMIN === $mode) {
|
||||
// if ($user->find('teamInternalId', $project->getAttribute('teamInternalId'), 'memberships')) {
|
||||
// Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
// } else {
|
||||
// $user = new Document([]);
|
||||
// }
|
||||
// }
|
||||
|
||||
$authJWT = $request->getHeader('x-appwrite-jwt', '');
|
||||
|
||||
if (!empty($authJWT) && !$project->isEmpty()) { // JWT authentication
|
||||
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 3600, 0);
|
||||
|
||||
try {
|
||||
$payload = $jwt->decode($authJWT);
|
||||
} catch (JWTException $error) {
|
||||
throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage());
|
||||
}
|
||||
|
||||
$jwtUserId = $payload['userId'] ?? '';
|
||||
if (!empty($jwtUserId)) {
|
||||
$user = $dbForProject->getDocument('users', $jwtUserId);
|
||||
}
|
||||
|
||||
$jwtSessionId = $payload['sessionId'] ?? '';
|
||||
if (!empty($jwtSessionId)) {
|
||||
if (empty($user->find('$id', $jwtSessionId, 'sessions'))) { // Match JWT to active token
|
||||
$user = new Document([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->setMetadata('user', $user->getId());
|
||||
$dbForPlatform->setMetadata('user', $user->getId());
|
||||
|
||||
return $user;
|
||||
}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForPlatform']);
|
||||
|
||||
App::setResource('project', function ($dbForPlatform, $request, $console) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
/** @var Utopia\Database\Document $console */
|
||||
|
||||
$projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', ''));
|
||||
|
||||
if (empty($projectId) || $projectId === 'console') {
|
||||
return $console;
|
||||
}
|
||||
|
||||
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
|
||||
return $project;
|
||||
}, ['dbForPlatform', 'request', 'console']);
|
||||
|
||||
App::setResource('session', function (Document $user) {
|
||||
if ($user->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret);
|
||||
|
||||
if (!$sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {/** @var Document $session */
|
||||
if ($sessionId === $session->getId()) {
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}, ['user']);
|
||||
|
||||
App::setResource('console', function () {
|
||||
return new Document(Config::getParam('console'));
|
||||
}, []);
|
||||
|
||||
App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform, Cache $cache, Document $project) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
|
||||
try {
|
||||
$dsn = new DSN($project->getAttribute('database'));
|
||||
} catch (\InvalidArgumentException) {
|
||||
// TODO: Temporary until all projects are using shared tables
|
||||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get($dsn->getHost())
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
|
||||
$database
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
return $database;
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'project']);
|
||||
|
||||
App::setResource('dbForPlatform', function (Group $pools, Cache $cache) {
|
||||
$dbAdapter = $pools
|
||||
->get('console')
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
|
||||
$database
|
||||
->setNamespace('_console')
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', 'console')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
return $database;
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) {
|
||||
$databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools
|
||||
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, &$databases) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
|
||||
try {
|
||||
$dsn = new DSN($project->getAttribute('database'));
|
||||
} catch (\InvalidArgumentException) {
|
||||
// TODO: Temporary until all projects are using shared tables
|
||||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
$configure = (function (Database $database) use ($project, $dsn) {
|
||||
$database
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
});
|
||||
|
||||
if (isset($databases[$dsn->getHost()])) {
|
||||
$database = $databases[$dsn->getHost()];
|
||||
$configure($database);
|
||||
return $database;
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get($dsn->getHost())
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
$databases[$dsn->getHost()] = $database;
|
||||
$configure($database);
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
|
||||
App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database = null;
|
||||
return function (?Document $project = null) use ($pools, $cache, $database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
return $database;
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get('logs')
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database(
|
||||
$dbAdapter,
|
||||
$cache
|
||||
);
|
||||
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
// set tenant
|
||||
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
}
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('cache', function (Group $pools) {
|
||||
$list = Config::getParam('pools-cache', []);
|
||||
$adapters = [];
|
||||
|
||||
foreach ($list as $value) {
|
||||
$adapters[] = $pools
|
||||
->get($value)
|
||||
->pop()
|
||||
->getResource()
|
||||
;
|
||||
}
|
||||
|
||||
return new Cache(new Sharding($adapters));
|
||||
}, ['pools']);
|
||||
|
||||
App::setResource('redis', function () {
|
||||
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
|
||||
$port = System::getEnv('_APP_REDIS_PORT', 6379);
|
||||
$pass = System::getEnv('_APP_REDIS_PASS', '');
|
||||
|
||||
$redis = new \Redis();
|
||||
@$redis->pconnect($host, (int)$port);
|
||||
if ($pass) {
|
||||
$redis->auth($pass);
|
||||
}
|
||||
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
return $redis;
|
||||
});
|
||||
|
||||
App::setResource('timelimit', function (\Redis $redis) {
|
||||
return function (string $key, int $limit, int $time) use ($redis) {
|
||||
return new TimeLimitRedis($key, $limit, $time, $redis);
|
||||
};
|
||||
}, ['redis']);
|
||||
|
||||
App::setResource('deviceForLocal', function () {
|
||||
return new Local();
|
||||
});
|
||||
|
||||
App::setResource('deviceForFiles', function ($project) {
|
||||
return getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
App::setResource('deviceForSites', function ($project) {
|
||||
return getDevice(APP_STORAGE_SITES . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
App::setResource('deviceForFunctions', function ($project) {
|
||||
return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
App::setResource('deviceForBuilds', function ($project) {
|
||||
return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
function getDevice(string $root, string $connection = ''): Device
|
||||
{
|
||||
$connection = !empty($connection) ? $connection : System::getEnv('_APP_CONNECTIONS_STORAGE', '');
|
||||
|
||||
if (!empty($connection)) {
|
||||
$acl = 'private';
|
||||
$device = Storage::DEVICE_LOCAL;
|
||||
$accessKey = '';
|
||||
$accessSecret = '';
|
||||
$bucket = '';
|
||||
$region = '';
|
||||
$url = System::getEnv('_APP_STORAGE_S3_ENDPOINT', '');
|
||||
|
||||
try {
|
||||
$dsn = new DSN($connection);
|
||||
$device = $dsn->getScheme();
|
||||
$accessKey = $dsn->getUser() ?? '';
|
||||
$accessSecret = $dsn->getPassword() ?? '';
|
||||
$bucket = $dsn->getPath() ?? '';
|
||||
$region = $dsn->getParam('region');
|
||||
} catch (\Throwable $e) {
|
||||
Console::warning($e->getMessage() . 'Invalid DSN. Defaulting to Local device.');
|
||||
}
|
||||
|
||||
switch ($device) {
|
||||
case Storage::DEVICE_S3:
|
||||
return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl, $url);
|
||||
case STORAGE::DEVICE_DO_SPACES:
|
||||
$device = new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
$device->setHttpVersion(S3::HTTP_VERSION_1_1);
|
||||
return $device;
|
||||
case Storage::DEVICE_BACKBLAZE:
|
||||
return new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
case Storage::DEVICE_LINODE:
|
||||
return new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
case Storage::DEVICE_WASABI:
|
||||
return new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
case Storage::DEVICE_LOCAL:
|
||||
default:
|
||||
return new Local($root);
|
||||
}
|
||||
} else {
|
||||
switch (strtolower(System::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) ?? '')) {
|
||||
case Storage::DEVICE_LOCAL:
|
||||
default:
|
||||
return new Local($root);
|
||||
case Storage::DEVICE_S3:
|
||||
$s3AccessKey = System::getEnv('_APP_STORAGE_S3_ACCESS_KEY', '');
|
||||
$s3SecretKey = System::getEnv('_APP_STORAGE_S3_SECRET', '');
|
||||
$s3Region = System::getEnv('_APP_STORAGE_S3_REGION', '');
|
||||
$s3Bucket = System::getEnv('_APP_STORAGE_S3_BUCKET', '');
|
||||
$s3Acl = 'private';
|
||||
$s3EndpointUrl = System::getEnv('_APP_STORAGE_S3_ENDPOINT', '');
|
||||
return new S3($root, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl, $s3EndpointUrl);
|
||||
case Storage::DEVICE_DO_SPACES:
|
||||
$doSpacesAccessKey = System::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', '');
|
||||
$doSpacesSecretKey = System::getEnv('_APP_STORAGE_DO_SPACES_SECRET', '');
|
||||
$doSpacesRegion = System::getEnv('_APP_STORAGE_DO_SPACES_REGION', '');
|
||||
$doSpacesBucket = System::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', '');
|
||||
$doSpacesAcl = 'private';
|
||||
$device = new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl);
|
||||
$device->setHttpVersion(S3::HTTP_VERSION_1_1);
|
||||
return $device;
|
||||
case Storage::DEVICE_BACKBLAZE:
|
||||
$backblazeAccessKey = System::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', '');
|
||||
$backblazeSecretKey = System::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', '');
|
||||
$backblazeRegion = System::getEnv('_APP_STORAGE_BACKBLAZE_REGION', '');
|
||||
$backblazeBucket = System::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', '');
|
||||
$backblazeAcl = 'private';
|
||||
return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl);
|
||||
case Storage::DEVICE_LINODE:
|
||||
$linodeAccessKey = System::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', '');
|
||||
$linodeSecretKey = System::getEnv('_APP_STORAGE_LINODE_SECRET', '');
|
||||
$linodeRegion = System::getEnv('_APP_STORAGE_LINODE_REGION', '');
|
||||
$linodeBucket = System::getEnv('_APP_STORAGE_LINODE_BUCKET', '');
|
||||
$linodeAcl = 'private';
|
||||
return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl);
|
||||
case Storage::DEVICE_WASABI:
|
||||
$wasabiAccessKey = System::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', '');
|
||||
$wasabiSecretKey = System::getEnv('_APP_STORAGE_WASABI_SECRET', '');
|
||||
$wasabiRegion = System::getEnv('_APP_STORAGE_WASABI_REGION', '');
|
||||
$wasabiBucket = System::getEnv('_APP_STORAGE_WASABI_BUCKET', '');
|
||||
$wasabiAcl = 'private';
|
||||
return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
App::setResource('mode', function ($request) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
|
||||
/**
|
||||
* Defines the mode for the request:
|
||||
* - 'default' => Requests for Client and Server Side
|
||||
* - 'admin' => Request from the Console on non-console projects
|
||||
*/
|
||||
return $request->getParam('mode', $request->getHeader('x-appwrite-mode', APP_MODE_DEFAULT));
|
||||
}, ['request']);
|
||||
|
||||
App::setResource('geodb', function ($register) {
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
return $register->get('geodb');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('passwordsDictionary', function ($register) {
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
return $register->get('passwordsDictionary');
|
||||
}, ['register']);
|
||||
|
||||
|
||||
App::setResource('servers', function () {
|
||||
$platforms = Config::getParam('platforms');
|
||||
$server = $platforms[APP_PLATFORM_SERVER];
|
||||
|
||||
$languages = array_map(function ($language) {
|
||||
return strtolower($language['name']);
|
||||
}, $server['sdks']);
|
||||
|
||||
return $languages;
|
||||
});
|
||||
|
||||
App::setResource('promiseAdapter', function ($register) {
|
||||
return $register->get('promiseAdapter');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('schema', function ($utopia, $dbForProject) {
|
||||
|
||||
$complexity = function (int $complexity, array $args) {
|
||||
$queries = Query::parseQueries($args['queries'] ?? []);
|
||||
$query = Query::getByType($queries, [Query::TYPE_LIMIT])[0] ?? null;
|
||||
$limit = $query ? $query->getValue() : APP_LIMIT_LIST_DEFAULT;
|
||||
|
||||
return $complexity * $limit;
|
||||
};
|
||||
|
||||
$attributes = function (int $limit, int $offset) use ($dbForProject) {
|
||||
$attrs = Authorization::skip(fn () => $dbForProject->find('attributes', [
|
||||
Query::limit($limit),
|
||||
Query::offset($offset),
|
||||
]));
|
||||
|
||||
return \array_map(function ($attr) {
|
||||
return $attr->getArrayCopy();
|
||||
}, $attrs);
|
||||
};
|
||||
|
||||
$urls = [
|
||||
'list' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents";
|
||||
},
|
||||
'create' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents";
|
||||
},
|
||||
'read' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents/{$args['documentId']}";
|
||||
},
|
||||
'update' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents/{$args['documentId']}";
|
||||
},
|
||||
'delete' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents/{$args['documentId']}";
|
||||
},
|
||||
];
|
||||
|
||||
$params = [
|
||||
'list' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return [ 'queries' => $args['queries']];
|
||||
},
|
||||
'create' => function (string $databaseId, string $collectionId, array $args) {
|
||||
$id = $args['id'] ?? 'unique()';
|
||||
$permissions = $args['permissions'] ?? null;
|
||||
|
||||
unset($args['id']);
|
||||
unset($args['permissions']);
|
||||
|
||||
// Order must be the same as the route params
|
||||
return [
|
||||
'databaseId' => $databaseId,
|
||||
'documentId' => $id,
|
||||
'collectionId' => $collectionId,
|
||||
'data' => $args,
|
||||
'permissions' => $permissions,
|
||||
];
|
||||
},
|
||||
'update' => function (string $databaseId, string $collectionId, array $args) {
|
||||
$documentId = $args['id'];
|
||||
$permissions = $args['permissions'] ?? null;
|
||||
|
||||
unset($args['id']);
|
||||
unset($args['permissions']);
|
||||
|
||||
// Order must be the same as the route params
|
||||
return [
|
||||
'databaseId' => $databaseId,
|
||||
'collectionId' => $collectionId,
|
||||
'documentId' => $documentId,
|
||||
'data' => $args,
|
||||
'permissions' => $permissions,
|
||||
];
|
||||
},
|
||||
];
|
||||
|
||||
return Schema::build(
|
||||
$utopia,
|
||||
$complexity,
|
||||
$attributes,
|
||||
$urls,
|
||||
$params,
|
||||
);
|
||||
}, ['utopia', 'dbForProject']);
|
||||
|
||||
App::setResource('contributors', function () {
|
||||
$path = 'app/config/contributors.json';
|
||||
$list = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
|
||||
return $list;
|
||||
});
|
||||
|
||||
App::setResource('employees', function () {
|
||||
$path = 'app/config/employees.json';
|
||||
$list = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
|
||||
return $list;
|
||||
});
|
||||
|
||||
App::setResource('heroes', function () {
|
||||
$path = 'app/config/heroes.json';
|
||||
$list = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
|
||||
return $list;
|
||||
});
|
||||
|
||||
App::setResource('gitHub', function (Cache $cache) {
|
||||
return new VcsGitHub($cache);
|
||||
}, ['cache']);
|
||||
|
||||
App::setResource('requestTimestamp', function ($request) {
|
||||
//TODO: Move this to the Request class itself
|
||||
$timestampHeader = $request->getHeader('x-appwrite-timestamp');
|
||||
$requestTimestamp = null;
|
||||
if (!empty($timestampHeader)) {
|
||||
try {
|
||||
$requestTimestamp = new \DateTime($timestampHeader);
|
||||
} catch (\Throwable $e) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Invalid X-Appwrite-Timestamp header value');
|
||||
}
|
||||
}
|
||||
return $requestTimestamp;
|
||||
}, ['request']);
|
||||
|
||||
App::setResource('plan', function (array $plan = []) {
|
||||
return [];
|
||||
});
|
||||
|
||||
App::setResource('smsRates', function () {
|
||||
return [];
|
||||
});
|
||||
|
||||
App::setResource('team', function (Document $project, Database $dbForPlatform, App $utopia, Request $request) {
|
||||
$teamInternalId = '';
|
||||
if ($project->getId() !== 'console') {
|
||||
$teamInternalId = $project->getAttribute('teamInternalId', '');
|
||||
} else {
|
||||
$route = $utopia->match($request);
|
||||
$path = $route->getPath();
|
||||
if (str_starts_with($path, '/v1/projects/:projectId')) {
|
||||
$uri = $request->getURI();
|
||||
$pid = explode('/', $uri)[3];
|
||||
$p = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $pid));
|
||||
$teamInternalId = $p->getAttribute('teamInternalId', '');
|
||||
} elseif ($path === '/v1/projects') {
|
||||
$teamId = $request->getParam('teamId', '');
|
||||
$team = Authorization::skip(fn () => $dbForPlatform->getDocument('teams', $teamId));
|
||||
return $team;
|
||||
}
|
||||
}
|
||||
|
||||
$team = Authorization::skip(function () use ($dbForPlatform, $teamInternalId) {
|
||||
return $dbForPlatform->findOne('teams', [
|
||||
Query::equal('$internalId', [$teamInternalId]),
|
||||
]);
|
||||
});
|
||||
|
||||
return $team;
|
||||
}, ['project', 'dbForPlatform', 'utopia', 'request']);
|
||||
|
||||
App::setResource(
|
||||
'isResourceBlocked',
|
||||
fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false
|
||||
);
|
||||
|
||||
App::setResource('previewHostname', function (Request $request, ?Key $apiKey) {
|
||||
$allowed = false;
|
||||
|
||||
if (App::isDevelopment()) {
|
||||
$allowed = true;
|
||||
} elseif (!\is_null($apiKey) && $apiKey->getHostnameOverride() === true) {
|
||||
$allowed = true;
|
||||
}
|
||||
|
||||
if ($allowed) {
|
||||
$host = $request->getQuery('appwrite-hostname', $request->getHeader('x-appwrite-hostname', '')) ?? '';
|
||||
if (!empty($host)) {
|
||||
return $host;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}, ['request', 'apiKey']);
|
||||
|
||||
App::setResource('apiKey', function (Request $request, Document $project): ?Key {
|
||||
$key = $request->getHeader('x-appwrite-key');
|
||||
|
||||
if (empty($key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Key::decode($project, $key);
|
||||
}, ['request', 'project']);
|
||||
@@ -7,6 +7,8 @@
|
||||
<title>404 Not Found</title>
|
||||
|
||||
<style>
|
||||
@import url(https://fonts.bunny.net/css?family=fira-code:400|inter:400);
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -36,7 +38,7 @@
|
||||
background: var(--color-overlay-on-neutral, rgba(0, 0, 0, 0.06));
|
||||
color: var(--color-fgColor-neutral-secondary, #56565C);
|
||||
text-align: center;
|
||||
font-family: var(--font-family-sansSerif, Inter);
|
||||
font-family: var(--font-family-sansSerif, Inter), sans-serif;
|
||||
font-size: var(--font-size-S, 14px);
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
@@ -47,7 +49,7 @@
|
||||
h1 {
|
||||
color: var(--color-fgColor-neutral-primary, #2D2D31);
|
||||
text-align: center;
|
||||
font-family: var(--font-family-sansSerif, Inter);
|
||||
font-family: var(--font-family-sansSerif, Inter), sans-serif;
|
||||
font-size: var(--font-size-XXXL, 32px);
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
@@ -59,7 +61,7 @@
|
||||
|
||||
button {
|
||||
border-radius: var(--border-radius-S, 8px);
|
||||
font-family: var(--font-family-sansSerif, Inter);
|
||||
font-family: var(--font-family-sansSerif, Inter), sans-serif;
|
||||
font-size: var(--font-size-S, 14px);
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
@@ -88,7 +90,7 @@
|
||||
}
|
||||
|
||||
.brand p {
|
||||
font-family: var(--font-family-monospace, "Aeonik Fono");
|
||||
font-family: var(--font-family-monospace, "Fira Code"), monospace;
|
||||
font-size: var(--font-size-XS, 12px);
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
|
||||
@@ -139,7 +139,6 @@ $image = $this->getParam('image', '');
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
- _APP_FUNCTIONS_RUNTIMES
|
||||
- _APP_SITES_FRAMEWORKS
|
||||
- _APP_SITES_RUNTIMES
|
||||
- _APP_EXECUTOR_SECRET
|
||||
- _APP_EXECUTOR_HOST
|
||||
@@ -166,11 +165,10 @@ $image = $this->getParam('image', '');
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: <?php echo $organization; ?>/console:5.2.27
|
||||
image: <?php echo $organization; ?>/console:5.2.53
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
@@ -344,6 +342,8 @@ $image = $this->getParam('image', '');
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_EXECUTION
|
||||
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
|
||||
appwrite-worker-databases:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
|
||||
@@ -112,6 +112,8 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register,
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
|
||||
return $database;
|
||||
}, ['cache', 'register', 'message', 'project', 'dbForPlatform']);
|
||||
|
||||
@@ -173,6 +175,8 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
@@ -198,7 +202,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS)
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
// set tenant
|
||||
|
||||
@@ -44,16 +44,16 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-zlib": "*",
|
||||
"ext-sockets": "*",
|
||||
"appwrite/php-runtimes": "0.18.*",
|
||||
"appwrite/php-runtimes": "0.19.*",
|
||||
"appwrite/php-clamav": "2.0.*",
|
||||
"utopia-php/abuse": "0.51.*",
|
||||
"utopia-php/abuse": "0.52.*",
|
||||
"utopia-php/analytics": "0.10.*",
|
||||
"utopia-php/audit": "0.54.0",
|
||||
"utopia-php/audit": "0.55.*",
|
||||
"utopia-php/cache": "0.12.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/detector": "0.1.*",
|
||||
"utopia-php/database": "0.60.*",
|
||||
"utopia-php/database": "0.61.*",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
@@ -62,18 +62,18 @@
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
"utopia-php/messaging": "0.16.*",
|
||||
"utopia-php/migration": "0.6.*",
|
||||
"utopia-php/migration": "0.8.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.3",
|
||||
"utopia-php/pools": "0.5.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.7.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.8.*",
|
||||
"utopia-php/queue": "0.9.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
"utopia-php/storage": "0.18.*",
|
||||
"utopia-php/swoole": "0.8.*",
|
||||
"utopia-php/system": "0.9.*",
|
||||
"utopia-php/telemetry": "0.1.*",
|
||||
"utopia-php/vcs": "0.9.*",
|
||||
"utopia-php/vcs": "0.10.*",
|
||||
"utopia-php/websocket": "0.1.*",
|
||||
"matomo/device-detector": "6.1.*",
|
||||
"dragonmantank/cron-expression": "3.3.2",
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "6e6444246ba207b6bf88c20340835fb5",
|
||||
"content-hash": "e4281c45c1b60dade2ec8df58e6926d5",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -157,16 +157,16 @@
|
||||
},
|
||||
{
|
||||
"name": "appwrite/php-runtimes",
|
||||
"version": "0.18.1",
|
||||
"version": "0.19.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/runtimes.git",
|
||||
"reference": "97b5d97ae2c0fc9a2a374769eadff024f95783aa"
|
||||
"reference": "8d21483efc19b9d977e323188989ee67a188464b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/97b5d97ae2c0fc9a2a374769eadff024f95783aa",
|
||||
"reference": "97b5d97ae2c0fc9a2a374769eadff024f95783aa",
|
||||
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/8d21483efc19b9d977e323188989ee67a188464b",
|
||||
"reference": "8d21483efc19b9d977e323188989ee67a188464b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -206,9 +206,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/runtimes/issues",
|
||||
"source": "https://github.com/appwrite/runtimes/tree/0.18.1"
|
||||
"source": "https://github.com/appwrite/runtimes/tree/0.19.0"
|
||||
},
|
||||
"time": "2025-03-11T14:05:46+00:00"
|
||||
"time": "2025-03-25T22:37:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "beberlei/assert",
|
||||
@@ -709,16 +709,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v4.30.0",
|
||||
"version": "v4.30.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "e1d66682f6836aa87820400f0aa07d9eb566feb6"
|
||||
"reference": "f29ba8a30dfd940efb3a8a75dc44446539101f24"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/e1d66682f6836aa87820400f0aa07d9eb566feb6",
|
||||
"reference": "e1d66682f6836aa87820400f0aa07d9eb566feb6",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/f29ba8a30dfd940efb3a8a75dc44446539101f24",
|
||||
"reference": "f29ba8a30dfd940efb3a8a75dc44446539101f24",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -747,22 +747,22 @@
|
||||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.30.0"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.30.1"
|
||||
},
|
||||
"time": "2025-03-04T22:54:49+00:00"
|
||||
"time": "2025-03-13T21:08:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Jean85/pretty-package-versions.git",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10"
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -772,8 +772,9 @@
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"jean85/composer-provided-replaced-stub-package": "^1.0",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.6",
|
||||
"rector/rector": "^2.0",
|
||||
"vimeo/psalm": "^4.3 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -806,9 +807,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Jean85/pretty-package-versions/issues",
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0"
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1"
|
||||
},
|
||||
"time": "2024-11-18T16:19:46+00:00"
|
||||
"time": "2025-03-19T14:43:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
@@ -2371,16 +2372,16 @@
|
||||
},
|
||||
{
|
||||
"name": "ramsey/collection",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/collection.git",
|
||||
"reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109"
|
||||
"reference": "344572933ad0181accbf4ba763e85a0306a8c5e2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/collection/zipball/3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109",
|
||||
"reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109",
|
||||
"url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2",
|
||||
"reference": "344572933ad0181accbf4ba763e85a0306a8c5e2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2441,9 +2442,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/collection/issues",
|
||||
"source": "https://github.com/ramsey/collection/tree/2.1.0"
|
||||
"source": "https://github.com/ramsey/collection/tree/2.1.1"
|
||||
},
|
||||
"time": "2025-03-02T04:48:29+00:00"
|
||||
"time": "2025-03-22T05:38:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
@@ -3364,16 +3365,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.51.0",
|
||||
"version": "0.52.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "661687b03277f1d202a0e8cf9da6e58c97da2b5e"
|
||||
"reference": "a0d6421e7e5baa3ac02755496dca9fdeaa814b93"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/661687b03277f1d202a0e8cf9da6e58c97da2b5e",
|
||||
"reference": "661687b03277f1d202a0e8cf9da6e58c97da2b5e",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/a0d6421e7e5baa3ac02755496dca9fdeaa814b93",
|
||||
"reference": "a0d6421e7e5baa3ac02755496dca9fdeaa814b93",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3381,7 +3382,7 @@
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.60.*"
|
||||
"utopia-php/database": "0.*.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
@@ -3409,9 +3410,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.51.0"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.52.0"
|
||||
},
|
||||
"time": "2025-02-17T11:10:18+00:00"
|
||||
"time": "2025-03-06T03:48:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
@@ -3461,21 +3462,21 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.54.0",
|
||||
"version": "0.55.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975"
|
||||
"reference": "9f8cfe5fa5d5011b8dbf93b710236dfa91dc5518"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975",
|
||||
"reference": "1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/9f8cfe5fa5d5011b8dbf93b710236dfa91dc5518",
|
||||
"reference": "9f8cfe5fa5d5011b8dbf93b710236dfa91dc5518",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.60.*"
|
||||
"utopia-php/database": "0.*.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
@@ -3502,9 +3503,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.54.0"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.55.0"
|
||||
},
|
||||
"time": "2025-02-25T07:21:07+00:00"
|
||||
"time": "2025-03-06T03:47:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
@@ -3705,16 +3706,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.60.6",
|
||||
"version": "0.61.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "f3c9aa964b39c6205069f038a26e709a15541406"
|
||||
"reference": "349fbdf4bc088f7775c7dfb8b80239a617a88436"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/f3c9aa964b39c6205069f038a26e709a15541406",
|
||||
"reference": "f3c9aa964b39c6205069f038a26e709a15541406",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/349fbdf4bc088f7775c7dfb8b80239a617a88436",
|
||||
"reference": "349fbdf4bc088f7775c7dfb8b80239a617a88436",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3755,22 +3756,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.60.6"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.61.2"
|
||||
},
|
||||
"time": "2025-03-05T01:23:14+00:00"
|
||||
"time": "2025-03-15T11:47:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/detector.git",
|
||||
"reference": "5dcabbfcf99731f3a37d86b7cb1e93c968baf64b"
|
||||
"reference": "8617ea205738743ef3363ad95791139e82ae44d5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/detector/zipball/5dcabbfcf99731f3a37d86b7cb1e93c968baf64b",
|
||||
"reference": "5dcabbfcf99731f3a37d86b7cb1e93c968baf64b",
|
||||
"url": "https://api.github.com/repos/utopia-php/detector/zipball/8617ea205738743ef3363ad95791139e82ae44d5",
|
||||
"reference": "8617ea205738743ef3363ad95791139e82ae44d5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3800,9 +3801,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/detector/issues",
|
||||
"source": "https://github.com/utopia-php/detector/tree/0.1.1"
|
||||
"source": "https://github.com/utopia-php/detector/tree/0.1.2"
|
||||
},
|
||||
"time": "2025-03-08T22:25:49+00:00"
|
||||
"time": "2025-03-11T13:01:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
@@ -4204,16 +4205,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.6.20",
|
||||
"version": "0.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba"
|
||||
"reference": "36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba",
|
||||
"reference": "8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab",
|
||||
"reference": "36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4221,7 +4222,7 @@
|
||||
"ext-curl": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": ">=8.1",
|
||||
"utopia-php/database": "0.60.*",
|
||||
"utopia-php/database": "0.61.*",
|
||||
"utopia-php/dsn": "0.2.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/storage": "0.18.*"
|
||||
@@ -4254,9 +4255,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.6.20"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.8.1"
|
||||
},
|
||||
"time": "2025-02-17T11:02:15+00:00"
|
||||
"time": "2025-03-18T07:48:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
@@ -4370,16 +4371,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/platform",
|
||||
"version": "0.7.3",
|
||||
"version": "0.7.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/platform.git",
|
||||
"reference": "463c2d817c893d7dbb678c2eac7a8291f2710e25"
|
||||
"reference": "a5b93d8177702ec458c3af9137663133c012b71b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/463c2d817c893d7dbb678c2eac7a8291f2710e25",
|
||||
"reference": "463c2d817c893d7dbb678c2eac7a8291f2710e25",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/a5b93d8177702ec458c3af9137663133c012b71b",
|
||||
"reference": "a5b93d8177702ec458c3af9137663133c012b71b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4388,7 +4389,7 @@
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/queue": "0.8.*"
|
||||
"utopia-php/queue": "0.9.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
@@ -4414,31 +4415,32 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/platform/issues",
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.3"
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.4"
|
||||
},
|
||||
"time": "2025-02-04T15:09:00+00:00"
|
||||
"time": "2025-03-13T13:00:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
"version": "0.5.0",
|
||||
"version": "0.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/pools.git",
|
||||
"reference": "6f716a213a08db95eda1b5dddfa90983c1834817"
|
||||
"reference": "ad64d45afda08ec8b29e2642a8d18075964d40bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/6f716a213a08db95eda1b5dddfa90983c1834817",
|
||||
"reference": "6f716a213a08db95eda1b5dddfa90983c1834817",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/ad64d45afda08ec8b29e2642a8d18075964d40bf",
|
||||
"reference": "ad64d45afda08ec8b29e2642a8d18075964d40bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0"
|
||||
"php": ">=8.3",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.8.*",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
"laravel/pint": "1.*",
|
||||
"phpstan/phpstan": "1.*",
|
||||
"phpunit/phpunit": "11.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -4465,9 +4467,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/pools/issues",
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.5.0"
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.7.0"
|
||||
},
|
||||
"time": "2024-04-19T11:11:54+00:00"
|
||||
"time": "2025-03-18T03:55:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/preloader",
|
||||
@@ -4524,16 +4526,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/queue",
|
||||
"version": "0.8.6",
|
||||
"version": "0.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/queue.git",
|
||||
"reference": "b713b997285c29d120bbcbe3d6e93762d850f87c"
|
||||
"reference": "077075f1d57afa430f76c35ed3bf4616e0eee8e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/b713b997285c29d120bbcbe3d6e93762d850f87c",
|
||||
"reference": "b713b997285c29d120bbcbe3d6e93762d850f87c",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/077075f1d57afa430f76c35ed3bf4616e0eee8e7",
|
||||
"reference": "077075f1d57afa430f76c35ed3bf4616e0eee8e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4583,9 +4585,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/queue/issues",
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.8.6"
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.9.0"
|
||||
},
|
||||
"time": "2025-02-10T03:35:00+00:00"
|
||||
"time": "2025-03-13T12:22:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
@@ -4805,16 +4807,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/telemetry",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/telemetry.git",
|
||||
"reference": "d35f2f0632f4ee0be63fb7ace6a94a6adda71a80"
|
||||
"reference": "437f0021777f0e575dfb9e8a1a081b3aed75e33f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/telemetry/zipball/d35f2f0632f4ee0be63fb7ace6a94a6adda71a80",
|
||||
"reference": "d35f2f0632f4ee0be63fb7ace6a94a6adda71a80",
|
||||
"url": "https://api.github.com/repos/utopia-php/telemetry/zipball/437f0021777f0e575dfb9e8a1a081b3aed75e33f",
|
||||
"reference": "437f0021777f0e575dfb9e8a1a081b3aed75e33f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4835,7 +4837,7 @@
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\": "src/"
|
||||
"Utopia\\Telemetry\\": "src/Telemetry"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -4849,22 +4851,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/telemetry/issues",
|
||||
"source": "https://github.com/utopia-php/telemetry/tree/0.1.0"
|
||||
"source": "https://github.com/utopia-php/telemetry/tree/0.1.1"
|
||||
},
|
||||
"time": "2024-11-13T10:29:53+00:00"
|
||||
"time": "2025-03-17T11:57:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/vcs",
|
||||
"version": "0.9.3",
|
||||
"version": "0.10.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/vcs.git",
|
||||
"reference": "865a00c67e81a20938b883f9aa802303790dd3b5"
|
||||
"reference": "6be02650cc361764900ade8c129f309df263eb74"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/865a00c67e81a20938b883f9aa802303790dd3b5",
|
||||
"reference": "865a00c67e81a20938b883f9aa802303790dd3b5",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/6be02650cc361764900ade8c129f309df263eb74",
|
||||
"reference": "6be02650cc361764900ade8c129f309df263eb74",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4882,8 +4884,7 @@
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\VCS\\": "src/VCS",
|
||||
"Utopia\\Detector\\": "src/Detector"
|
||||
"Utopia\\VCS\\": "src/VCS"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -4899,9 +4900,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/vcs/issues",
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.9.3"
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.10.1"
|
||||
},
|
||||
"time": "2025-02-26T16:33:35+00:00"
|
||||
"time": "2025-03-18T11:44:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
@@ -5088,16 +5089,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.40.7",
|
||||
"version": "0.40.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "9e89b0bc4d8e6c81817d27096629f34a149fa873"
|
||||
"reference": "054ac96285caf4f77879087b2416a5ddb8263051"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9e89b0bc4d8e6c81817d27096629f34a149fa873",
|
||||
"reference": "9e89b0bc4d8e6c81817d27096629f34a149fa873",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/054ac96285caf4f77879087b2416a5ddb8263051",
|
||||
"reference": "054ac96285caf4f77879087b2416a5ddb8263051",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5133,9 +5134,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.7"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.10"
|
||||
},
|
||||
"time": "2025-03-12T08:43:55+00:00"
|
||||
"time": "2025-03-25T13:44:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -5362,16 +5363,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/pint",
|
||||
"version": "v1.21.1",
|
||||
"version": "v1.21.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/pint.git",
|
||||
"reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86"
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/c44bffbb2334e90fba560933c45948fa4a3f3e86",
|
||||
"reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5382,9 +5383,9 @@
|
||||
"php": "^8.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.70.2",
|
||||
"illuminate/view": "^11.44.1",
|
||||
"larastan/larastan": "^3.1.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.72.0",
|
||||
"illuminate/view": "^11.44.2",
|
||||
"larastan/larastan": "^3.2.0",
|
||||
"laravel-zero/framework": "^11.36.1",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/termwind": "^2.3",
|
||||
@@ -5424,7 +5425,7 @@
|
||||
"issues": "https://github.com/laravel/pint/issues",
|
||||
"source": "https://github.com/laravel/pint"
|
||||
},
|
||||
"time": "2025-03-11T03:22:21+00:00"
|
||||
"time": "2025-03-14T22:31:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
||||
@@ -166,7 +166,6 @@ services:
|
||||
- _APP_COMPUTE_MEMORY
|
||||
- _APP_FUNCTIONS_RUNTIMES
|
||||
- _APP_SITES_RUNTIMES
|
||||
- _APP_SITES_FRAMEWORKS
|
||||
- _APP_DOMAIN_SITES
|
||||
- _APP_EXECUTOR_SECRET
|
||||
- _APP_EXECUTOR_HOST
|
||||
@@ -206,7 +205,7 @@ services:
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: appwrite/console:5.3.0-sites-rc.24
|
||||
image: appwrite/console:5.3.0-sites-rc.31
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
@@ -765,7 +764,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
- _APP_STATS_RESOURCES_INTERVAL
|
||||
|
||||
|
||||
appwrite-worker-stats-resources:
|
||||
entrypoint: worker-stats-resources
|
||||
<<: *x-logging
|
||||
@@ -796,7 +795,7 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
|
||||
appwrite-worker-stats-usage:
|
||||
entrypoint: worker-stats-usage
|
||||
<<: *x-logging
|
||||
@@ -859,7 +858,7 @@ services:
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
- _APP_STATS_USAGE_DUAL_WRITING_DBS
|
||||
|
||||
|
||||
appwrite-task-scheduler-functions:
|
||||
entrypoint: schedule-functions
|
||||
<<: *x-logging
|
||||
@@ -962,7 +961,7 @@ services:
|
||||
hostname: exc1
|
||||
<<: *x-logging
|
||||
stop_signal: SIGINT
|
||||
image: openruntimes/executor:0.7.10
|
||||
image: openruntimes/executor:0.7.13
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
@@ -59,7 +59,7 @@ My Awesome Function
|
||||
You can now deploy this function using
|
||||
|
||||
```sh
|
||||
$ appwrite deploy function
|
||||
$ appwrite push function
|
||||
|
||||
? Which functions would you like to deploy? My Awesome Function (61d1a4c81dfcd95bc834)
|
||||
ℹ Info Deploying function My Awesome Function ( 61d1a4c81dfcd95bc834 )
|
||||
@@ -73,7 +73,7 @@ Your function has now been deployed on your Appwrite server! As soon as the buil
|
||||
Similarly, you can deploy all your collections to your Appwrite server using
|
||||
|
||||
```sh
|
||||
appwrite deploy collections
|
||||
appwrite push collections
|
||||
```
|
||||
|
||||
> ### Note
|
||||
@@ -98,7 +98,7 @@ $ appwrite users list
|
||||
|
||||
To create a document you can use the following command
|
||||
```sh
|
||||
$ appwrite database createDocument --collectionId <ID> --documentId 'unique()' --data '{ "Name": "Iron Man" }' --permissions 'read("any")' 'read("team:abc")'
|
||||
$ appwrite databases create-document --database-id <DATABASE_ID> --collection-id <COLLECTION_ID> --document-id "unique()" --data '{"name": "Walter O Brein"}' --permissions 'read("any")' 'read("team:abc")'
|
||||
```
|
||||
|
||||
### Some Gotchas
|
||||
@@ -140,4 +140,4 @@ The Appwrite CLI can also work in a CI environment. The initialisation of the CL
|
||||
|
||||
```sh
|
||||
appwrite client --endpoint http://localhost/v1 --projectId <PROJECT_ID> --key <API KEY>
|
||||
```
|
||||
```
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
## 14.0.0
|
||||
|
||||
* Breaking changes:
|
||||
* Changed the typing of `AppwriteException`'s response parameter from a `dynamic` object to an optional string (`?String`).
|
||||
|
||||
## 13.0.0
|
||||
|
||||
* Fixed realtime pong response.
|
||||
* Fixed issues with `chunkedUpload` method.
|
||||
* Fixed type mismatch bug where `List<dynamic>` was incorrectly causing runtime type errors.
|
||||
* Updated return type of `updateMfaChallenge()` from raw data to properly typed `models.Session` object.
|
||||
|
||||
## 12.0.0
|
||||
|
||||
* Support for Appwrite 1.6
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 15.0.0
|
||||
|
||||
* Breaking changes:
|
||||
* Changed the typing of `AppwriteException`'s response parameter from a `dynamic` object to an optional string (`?String`).
|
||||
|
||||
## 14.0.0
|
||||
|
||||
* Fixed realtime pong response.
|
||||
* Fixed issues with `chunkedUpload` method.
|
||||
|
||||
## 13.0.0
|
||||
|
||||
* Fixed realtime reconnection issues
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
stopOnFailure="true"
|
||||
>
|
||||
<extensions>
|
||||
<extension class="Appwrite\Tests\TestHook" />
|
||||
|
||||
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 521 KiB |
|
After Width: | Height: | Size: 506 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 306 KiB |
|
Before Width: | Height: | Size: 306 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 71 KiB |
@@ -24,6 +24,7 @@ class Key
|
||||
protected bool $bannerDisabled = false,
|
||||
protected bool $projectCheckDisabled = false,
|
||||
protected bool $previewAuthDisabled = false,
|
||||
protected bool $deploymentStatusIgnored = false,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -79,6 +80,11 @@ class Key
|
||||
return $this->previewAuthDisabled;
|
||||
}
|
||||
|
||||
public function isDeploymentStatusIgnored(): bool
|
||||
{
|
||||
return $this->deploymentStatusIgnored;
|
||||
}
|
||||
|
||||
public function isProjectCheckDisabled(): bool
|
||||
{
|
||||
return $this->projectCheckDisabled;
|
||||
@@ -139,6 +145,7 @@ class Key
|
||||
$bannerDisabled = $payload['bannerDisabled'] ?? false;
|
||||
$projectCheckDisabled = $payload['projectCheckDisabled'] ?? false;
|
||||
$previewAuthDisabled = $payload['previewAuthDisabled'] ?? false;
|
||||
$deploymentStatusIgnored = $payload['deploymentStatusIgnored'] ?? false;
|
||||
$scopes = \array_merge($payload['scopes'] ?? [], $scopes);
|
||||
|
||||
if (!$projectCheckDisabled && $projectId !== $project->getId()) {
|
||||
@@ -156,7 +163,8 @@ class Key
|
||||
$hostnameOverride,
|
||||
$bannerDisabled,
|
||||
$projectCheckDisabled,
|
||||
$previewAuthDisabled
|
||||
$previewAuthDisabled,
|
||||
$deploymentStatusIgnored
|
||||
);
|
||||
case API_KEY_STANDARD:
|
||||
$key = $project->find(
|
||||
|
||||
@@ -156,7 +156,6 @@ class Exception extends \Exception
|
||||
|
||||
/** Sites */
|
||||
public const SITE_NOT_FOUND = 'site_not_found';
|
||||
public const SITE_FRAMEWORK_UNSUPPORTED = 'site_framework_unsupported';
|
||||
public const SITE_TEMPLATE_NOT_FOUND = 'site_template_not_found';
|
||||
|
||||
/** Functions */
|
||||
@@ -175,6 +174,7 @@ class Exception extends \Exception
|
||||
public const BUILD_NOT_READY = 'build_not_ready';
|
||||
public const BUILD_IN_PROGRESS = 'build_in_progress';
|
||||
public const BUILD_ALREADY_COMPLETED = 'build_already_completed';
|
||||
public const BUILD_FAILED = 'build_failed';
|
||||
|
||||
/** Execution */
|
||||
public const EXECUTION_NOT_FOUND = 'execution_not_found';
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Appwrite\Platform\Modules\Compute;
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Query;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
@@ -39,26 +38,29 @@ class Base extends Action
|
||||
throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND);
|
||||
}
|
||||
|
||||
// TODO: Support tag and commit in future
|
||||
$commitDetails = [];
|
||||
$branchUrl = "";
|
||||
$providerBranch = "";
|
||||
|
||||
// TODO: Support tag in future
|
||||
if ($referenceType === 'branch') {
|
||||
$providerBranch = empty($reference) ? $function->getAttribute('providerBranch', 'main') : $reference;
|
||||
}
|
||||
|
||||
$authorUrl = "https://github.com/$owner";
|
||||
$repositoryUrl = "https://github.com/$owner/$repositoryName";
|
||||
$branchUrl = "https://github.com/$owner/$repositoryName/tree/$providerBranch";
|
||||
|
||||
$commitDetails = [];
|
||||
if ($template->isEmpty()) {
|
||||
$branchUrl = "https://github.com/$owner/$repositoryName/tree/$providerBranch";
|
||||
try {
|
||||
$commitDetails = $github->getLatestCommit($owner, $repositoryName, $providerBranch);
|
||||
} catch (\Throwable $error) {
|
||||
Console::warning('Failed to get latest commit details');
|
||||
Console::warning($error->getMessage());
|
||||
Console::warning($error->getTraceAsString());
|
||||
// Ignore; deployment can continue
|
||||
}
|
||||
} elseif ($referenceType === 'commit') {
|
||||
try {
|
||||
$commitDetails = $github->getCommit($owner, $repositoryName, $reference);
|
||||
} catch (\Throwable $error) {
|
||||
// Ignore; deployment can continue
|
||||
}
|
||||
}
|
||||
|
||||
$repositoryUrl = "https://github.com/$owner/$repositoryName";
|
||||
|
||||
$deployment = $dbForProject->createDocument('deployments', new Document([
|
||||
'$id' => $deploymentId,
|
||||
'$permissions' => [
|
||||
@@ -82,7 +84,7 @@ class Base extends Action
|
||||
'providerRepositoryOwner' => $owner,
|
||||
'providerRepositoryUrl' => $repositoryUrl,
|
||||
'providerCommitHash' => $commitDetails['commitHash'] ?? '',
|
||||
'providerCommitAuthorUrl' => $authorUrl,
|
||||
'providerCommitAuthorUrl' => $commitDetails['commitAuthorUrl'] ?? '',
|
||||
'providerCommitAuthor' => $commitDetails['commitAuthor'] ?? '',
|
||||
'providerCommitMessage' => mb_strimwidth($commitDetails['commitMessage'] ?? '', 0, 255, '...'),
|
||||
'providerCommitUrl' => $commitDetails['commitUrl'] ?? '',
|
||||
@@ -92,6 +94,13 @@ class Base extends Action
|
||||
'activate' => $activate,
|
||||
]));
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
@@ -140,7 +149,6 @@ class Base extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$authorUrl = "https://github.com/$owner";
|
||||
$repositoryUrl = "https://github.com/$owner/$repositoryName";
|
||||
|
||||
$commands = [];
|
||||
@@ -163,6 +171,8 @@ class Base extends Action
|
||||
'resourceType' => 'sites',
|
||||
'buildCommands' => implode(' && ', $commands),
|
||||
'buildOutput' => $site->getAttribute('outputDirectory', ''),
|
||||
'adapter' => $site->getAttribute('adapter', ''),
|
||||
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
|
||||
'type' => 'vcs',
|
||||
'installationId' => $installation->getId(),
|
||||
'installationInternalId' => $installation->getInternalId(),
|
||||
@@ -174,7 +184,7 @@ class Base extends Action
|
||||
'providerRepositoryOwner' => $owner,
|
||||
'providerRepositoryUrl' => $repositoryUrl,
|
||||
'providerCommitHash' => $commitDetails['commitHash'] ?? '',
|
||||
'providerCommitAuthorUrl' => $authorUrl,
|
||||
'providerCommitAuthorUrl' => $commitDetails['commitAuthorUrl'] ?? '',
|
||||
'providerCommitAuthor' => $commitDetails['commitAuthor'] ?? '',
|
||||
'providerCommitMessage' => mb_strimwidth($commitDetails['commitMessage'] ?? '', 0, 255, '...'),
|
||||
'providerCommitUrl' => $commitDetails['commitUrl'] ?? '',
|
||||
@@ -184,6 +194,13 @@ class Base extends Action
|
||||
'activate' => $activate,
|
||||
]));
|
||||
|
||||
$site = $site
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('sites', $site->getId(), $site);
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$domain = ID::unique() . "." . $sitesDomain;
|
||||
|
||||
@@ -207,6 +224,8 @@ class Base extends Action
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
|
||||
|
||||
@@ -234,11 +234,19 @@ class Create extends Action
|
||||
'buildCommands' => $commands,
|
||||
'sourcePath' => $path,
|
||||
'sourceSize' => $fileSize,
|
||||
'totalSize' => $fileSize,
|
||||
'search' => implode(' ', [$deploymentId, $entrypoint]),
|
||||
'activate' => $activate,
|
||||
'sourceMetadata' => $metadata,
|
||||
'type' => $type
|
||||
]));
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
} else {
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment->setAttribute('sourceSize', $fileSize)->setAttribute('sourceMetadata', $metadata));
|
||||
}
|
||||
@@ -264,6 +272,7 @@ class Create extends Action
|
||||
'buildCommands' => $commands,
|
||||
'sourcePath' => $path,
|
||||
'sourceSize' => $fileSize,
|
||||
'totalSize' => $fileSize,
|
||||
'sourceChunksTotal' => $chunks,
|
||||
'sourceChunksUploaded' => $chunksUploaded,
|
||||
'search' => implode(' ', [$deploymentId, $entrypoint]),
|
||||
@@ -271,6 +280,13 @@ class Create extends Action
|
||||
'sourceMetadata' => $metadata,
|
||||
'type' => $type
|
||||
]));
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
} else {
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment->setAttribute('sourceChunksUploaded', $chunksUploaded)->setAttribute('sourceMetadata', $metadata));
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
@@ -96,10 +97,28 @@ class Delete extends Action
|
||||
}
|
||||
}
|
||||
|
||||
if ($function->getAttribute('latestDeploymentId') === $deployment->getId()) {
|
||||
$latestDeployment = $dbForProject->findOne('deployments', [
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::equal('resourceInternalId', [$function->getInternalId()]),
|
||||
Query::orderDesc('$createdAt'),
|
||||
]);
|
||||
$function = $dbForProject->updateDocument(
|
||||
'functions',
|
||||
$function->getId(),
|
||||
$function
|
||||
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->isEmpty() ? '' : $latestDeployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getInternalId())
|
||||
->setAttribute('latestDeploymentId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getId())
|
||||
->setAttribute('latestDeploymentStatus', $latestDeployment->isEmpty() ? '' : $latestDeployment->getAttribute('status', ''))
|
||||
);
|
||||
}
|
||||
|
||||
if ($function->getAttribute('deploymentId') === $deployment->getId()) { // Reset function deployment
|
||||
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
|
||||
'deploymentId' => '',
|
||||
'deploymentInternalId' => '',
|
||||
'deploymentCreatedAt' => '',
|
||||
])));
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ class Create extends Action
|
||||
'$internalId' => '',
|
||||
'$id' => $deploymentId,
|
||||
'sourcePath' => $destination,
|
||||
'totalSize' => $deployment->getAttribute('sourceSize', 0),
|
||||
'entrypoint' => $function->getAttribute('entrypoint'),
|
||||
'buildCommands' => $function->getAttribute('commands', ''),
|
||||
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),
|
||||
@@ -112,6 +113,13 @@ class Create extends Action
|
||||
'buildLogs' => '',
|
||||
]));
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
|
||||
@@ -95,6 +95,11 @@ class Update extends Action
|
||||
'status' => 'canceled'
|
||||
]));
|
||||
|
||||
if ($deployment->getInternalId() === $function->getAttribute('latestDeploymentInternalId', '')) {
|
||||
$function = $function->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
}
|
||||
|
||||
try {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
$executor->deleteRuntime($project->getId(), $deploymentId . "-build");
|
||||
|
||||
@@ -150,6 +150,13 @@ class Create extends Base
|
||||
'activate' => $activate,
|
||||
]));
|
||||
|
||||
$function = $function
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
|
||||
@@ -59,9 +59,9 @@ class Create extends Base
|
||||
],
|
||||
))
|
||||
->param('functionId', '', new UID(), 'Function ID.')
|
||||
// TODO: Support tag and commit in future
|
||||
->param('type', '', new WhiteList(['branch']), 'Type of reference passed. Allowed values are: branch')
|
||||
->param('reference', '', new Text(255), 'VCS reference to create deployment from. Depending on type this can be: branch name')
|
||||
// TODO: Support tag in future
|
||||
->param('type', '', new WhiteList(['branch', 'commit']), 'Type of reference passed. Allowed values are: branch, commit')
|
||||
->param('reference', '', new Text(255), 'VCS reference to create deployment from. Depending on type this can be: branch name, commit hash')
|
||||
->param('activate', false, new Boolean(), 'Automatically activate the deployment when it is finished building.', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
|
||||
@@ -300,7 +300,7 @@ class Create extends Base
|
||||
];
|
||||
|
||||
$schedule = $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'),
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => ScheduleExecutions::getSupportedResource(),
|
||||
'resourceId' => $execution->getId(),
|
||||
'resourceInternalId' => $execution->getInternalId(),
|
||||
|
||||
@@ -76,7 +76,7 @@ class Create extends Base
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, (int) System::getEnv('_APP_COMPUTE_TIMEOUT', 900)), 'Function maximum execution time in seconds.', true)
|
||||
->param('enabled', true, new Boolean(), 'Is function enabled? When set to \'disabled\', users cannot access the function but Server SDKs with and API key can still access the function. No data is lost when this is toggled.', true)
|
||||
->param('logging', true, new Boolean(), 'Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.', true)
|
||||
->param('logging', true, new Boolean(), 'When disabled, executions will exclude logs and errors, and will be slightly faster.', true)
|
||||
->param('entrypoint', '', new Text(1028, 0), 'Entrypoint File. This path is relative to the "providerRootDirectory".', true)
|
||||
->param('commands', '', new Text(8192, 0), 'Build Commands.', true)
|
||||
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for API key auto-generated for every execution. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', true)
|
||||
@@ -207,7 +207,7 @@ class Create extends Base
|
||||
|
||||
$schedule = Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'), // Todo replace with projects region
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $function->getId(),
|
||||
'resourceInternalId' => $function->getInternalId(),
|
||||
|
||||
@@ -93,6 +93,7 @@ class Update extends Base
|
||||
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'deploymentCreatedAt' => $deployment->getCreatedAt(),
|
||||
])));
|
||||
|
||||
// Inform scheduler if function is still active
|
||||
|
||||
@@ -80,7 +80,7 @@ class Update extends Base
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, (int) System::getEnv('_APP_COMPUTE_TIMEOUT', 900)), 'Maximum execution time in seconds.', true)
|
||||
->param('enabled', true, new Boolean(), 'Is function enabled? When set to \'disabled\', users cannot access the function but Server SDKs with and API key can still access the function. No data is lost when this is toggled.', true)
|
||||
->param('logging', true, new Boolean(), 'Whether executions will be logged. When set to false, executions will not be logged, but will reduce resource used by your Appwrite project.', true)
|
||||
->param('logging', true, new Boolean(), 'When disabled, executions will exclude logs and errors, and will be slightly faster.', true)
|
||||
->param('entrypoint', '', new Text(1028, 0), 'Entrypoint File. This path is relative to the "providerRootDirectory".', true)
|
||||
->param('commands', '', new Text(8192, 0), 'Build Commands.', true)
|
||||
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('scopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'List of scopes allowed for API Key auto-generated for every execution. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', true)
|
||||
|
||||
@@ -41,6 +41,8 @@ use Utopia\Storage\Device\Local;
|
||||
use Utopia\System\System;
|
||||
use Utopia\VCS\Adapter\Git\GitHub;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
class Builds extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
@@ -91,8 +93,23 @@ class Builds extends Action
|
||||
* @return void
|
||||
* @throws \Utopia\Database\Exception
|
||||
*/
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, StatsUsage $queueForStatsUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Device $deviceForSites, callable $isResourceBlocked, Device $deviceForFiles, Log $log): void
|
||||
{
|
||||
public function action(
|
||||
Message $message,
|
||||
Document $project,
|
||||
Database $dbForPlatform,
|
||||
Event $queueForEvents,
|
||||
Webhook $queueForWebhooks,
|
||||
Func $queueForFunctions,
|
||||
Realtime $queueForRealtime,
|
||||
StatsUsage $queueForStatsUsage,
|
||||
Cache $cache,
|
||||
Database $dbForProject,
|
||||
Device $deviceForFunctions,
|
||||
Device $deviceForSites,
|
||||
callable $isResourceBlocked,
|
||||
Device $deviceForFiles,
|
||||
Log $log
|
||||
): void {
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
if (empty($payload)) {
|
||||
@@ -112,7 +129,25 @@ class Builds extends Action
|
||||
case BUILD_TYPE_RETRY:
|
||||
Console::info('Creating build for deployment: ' . $deployment->getId());
|
||||
$github = new GitHub($cache);
|
||||
$this->buildDeployment($deviceForFunctions, $deviceForSites, $deviceForFiles, $queueForWebhooks, $queueForFunctions, $queueForRealtime, $queueForEvents, $queueForStatsUsage, $dbForPlatform, $dbForProject, $github, $project, $resource, $deployment, $template, $isResourceBlocked, $log);
|
||||
$this->buildDeployment(
|
||||
$deviceForFunctions,
|
||||
$deviceForSites,
|
||||
$deviceForFiles,
|
||||
$queueForWebhooks,
|
||||
$queueForFunctions,
|
||||
$queueForRealtime,
|
||||
$queueForEvents,
|
||||
$queueForStatsUsage,
|
||||
$dbForPlatform,
|
||||
$dbForProject,
|
||||
$github,
|
||||
$project,
|
||||
$resource,
|
||||
$deployment,
|
||||
$template,
|
||||
$isResourceBlocked,
|
||||
$log
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -142,9 +177,26 @@ class Builds extends Action
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function buildDeployment(Device $deviceForFunctions, Device $deviceForSites, Device $deviceForFiles, Webhook $queueForWebhooks, Func $queueForFunctions, Realtime $queueForRealtime, Event $queueForEvents, StatsUsage $queueForStatsUsage, Database $dbForPlatform, Database $dbForProject, GitHub $github, Document $project, Document $resource, Document $deployment, Document $template, callable $isResourceBlocked, Log $log): void
|
||||
{
|
||||
$resourceKey = match($resource->getCollection()) {
|
||||
protected function buildDeployment(
|
||||
Device $deviceForFunctions,
|
||||
Device $deviceForSites,
|
||||
Device $deviceForFiles,
|
||||
Webhook $queueForWebhooks,
|
||||
Func $queueForFunctions,
|
||||
Realtime $queueForRealtime,
|
||||
Event $queueForEvents,
|
||||
StatsUsage $queueForStatsUsage,
|
||||
Database $dbForPlatform,
|
||||
Database $dbForProject,
|
||||
GitHub $github,
|
||||
Document $project,
|
||||
Document $resource,
|
||||
Document $deployment,
|
||||
Document $template,
|
||||
callable $isResourceBlocked,
|
||||
Log $log
|
||||
): void {
|
||||
$resourceKey = match ($resource->getCollection()) {
|
||||
'functions' => 'functionId',
|
||||
'sites' => 'siteId',
|
||||
default => throw new \Exception('Invalid resource type')
|
||||
@@ -190,6 +242,12 @@ class Builds extends Action
|
||||
|
||||
// Realtime preparation
|
||||
$event = "{$resource->getCollection()}.[{$resourceKey}].deployments.[deploymentId].update";
|
||||
$queueForRealtime
|
||||
->setSubscribers(['console'])
|
||||
->setProject($project)
|
||||
->setEvent($event)
|
||||
->setParam($resourceKey, $resource->getId())
|
||||
->setParam('deploymentId', $deployment->getId());
|
||||
|
||||
$startTime = DateTime::now();
|
||||
$durationStart = \microtime(true);
|
||||
@@ -205,6 +263,15 @@ class Builds extends Action
|
||||
$deployment->setAttribute('status', 'processing');
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
|
||||
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
$source = $deployment->getAttribute('sourcePath', '');
|
||||
$installationId = $deployment->getAttribute('installationId', '');
|
||||
$providerRepositoryId = $deployment->getAttribute('providerRepositoryId', '');
|
||||
@@ -275,8 +342,13 @@ class Builds extends Action
|
||||
$directorySize = $device->getFileSize($source);
|
||||
$deployment
|
||||
->setAttribute('sourcePath', $source)
|
||||
->setAttribute('sourceSize', $directorySize);
|
||||
->setAttribute('sourceSize', $directorySize)
|
||||
->setAttribute('totalSize', $directorySize);
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
}
|
||||
} elseif ($isVcsEnabled) {
|
||||
// VCS and VCS+Temaplte
|
||||
@@ -384,15 +456,7 @@ class Builds extends Action
|
||||
$deployment->setAttribute('providerCommitUrl', "https://github.com/$cloneOwner/$cloneRepository/commit/$providerCommitHash");
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
/**
|
||||
* Trigger Realtime Event
|
||||
*/
|
||||
$queueForRealtime
|
||||
->setSubscribers(['console'])
|
||||
->setProject($project)
|
||||
->setEvent($event)
|
||||
->setParam($resourceKey, $resource->getId())
|
||||
->setParam('deploymentId', $deployment->getId())
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
}
|
||||
@@ -430,9 +494,14 @@ class Builds extends Action
|
||||
|
||||
$deployment
|
||||
->setAttribute('sourcePath', $source)
|
||||
->setAttribute('sourceSize', $directorySize);
|
||||
->setAttribute('sourceSize', $directorySize)
|
||||
->setAttribute('totalSize', $directorySize);
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
$this->runGitAction('processing', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform);
|
||||
}
|
||||
|
||||
@@ -440,6 +509,15 @@ class Builds extends Action
|
||||
$deployment->setAttribute('status', 'building');
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
|
||||
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
if ($isVcsEnabled) {
|
||||
$this->runGitAction('building', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform);
|
||||
}
|
||||
@@ -465,11 +543,6 @@ class Builds extends Action
|
||||
|
||||
/** Trigger Realtime Event */
|
||||
$queueForRealtime
|
||||
->setSubscribers(['console'])
|
||||
->setProject($project)
|
||||
->setEvent($event)
|
||||
->setParam($resourceKey, $resource->getId())
|
||||
->setParam('deploymentId', $deployment->getId())
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
@@ -577,7 +650,6 @@ class Builds extends Action
|
||||
try {
|
||||
$command = $version === 'v2' ? 'tar -zxf /tmp/code.tar.gz -C /usr/code && cd /usr/local/src/ && ./build.sh' : 'tar -zxf /tmp/code.tar.gz -C /mnt/code && helpers/build.sh "' . \trim(\escapeshellarg($command), "\'") . '"';
|
||||
|
||||
// TODO: Detect adapter if adapter is empty
|
||||
$response = $executor->createRuntime(
|
||||
deploymentId: $deployment->getId(),
|
||||
projectId: $project->getId(),
|
||||
@@ -598,13 +670,13 @@ class Builds extends Action
|
||||
$err = $error;
|
||||
}
|
||||
}),
|
||||
Co\go(function () use ($executor, $project, &$deployment, &$response, $dbForProject, $event, $timeout, &$err, $queueForRealtime, &$isCanceled, $resourceKey, $resource) {
|
||||
Co\go(function () use ($executor, $project, &$deployment, &$response, $dbForProject, $timeout, &$err, $queueForRealtime, &$isCanceled) {
|
||||
try {
|
||||
$executor->getLogs(
|
||||
deploymentId: $deployment->getId(),
|
||||
projectId: $project->getId(),
|
||||
timeout: $timeout,
|
||||
callback: function ($logs) use (&$response, &$err, $dbForProject, $event, $project, &$isCanceled, &$deployment, $queueForRealtime, $resourceKey, $resource) {
|
||||
callback: function ($logs) use (&$response, &$err, $dbForProject, &$isCanceled, &$deployment, $queueForRealtime) {
|
||||
if ($isCanceled) {
|
||||
return;
|
||||
}
|
||||
@@ -640,15 +712,7 @@ class Builds extends Action
|
||||
$deployment = $deployment->setAttribute('buildLogs', $currentLogs);
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
/**
|
||||
* Trigger Realtime Event
|
||||
*/
|
||||
$queueForRealtime
|
||||
->setSubscribers(['console'])
|
||||
->setProject($project)
|
||||
->setEvent($event)
|
||||
->setParam($resourceKey, $resource->getId())
|
||||
->setParam('deploymentId', $deployment->getId())
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
}
|
||||
@@ -706,6 +770,10 @@ class Builds extends Action
|
||||
$resource->setAttribute('adapter', $detection->getName());
|
||||
$resource->setAttribute('fallbackFile', $detection->getFallbackFile() ?? '');
|
||||
$resource = $dbForProject->updateDocument('sites', $resource->getId(), $resource);
|
||||
|
||||
$deployment->setAttribute('adapter', $detection->getName());
|
||||
$deployment->setAttribute('fallbackFile', $detection->getFallbackFile() ?? '');
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
} elseif ($adapter === 'ssr' && $detection->getName() === 'static') {
|
||||
throw new \Exception('Adapter mismatch. Detected: ' . $detection->getName() . ' does not match with the set adapter: ' . $adapter);
|
||||
}
|
||||
@@ -717,24 +785,24 @@ class Builds extends Action
|
||||
$deployment->setAttribute('buildStartAt', DateTime::format((new \DateTime())->setTimestamp(floor($response['startTime']))));
|
||||
$deployment->setAttribute('buildEndAt', $endTime);
|
||||
$deployment->setAttribute('buildDuration', \intval(\ceil($durationEnd - $durationStart)));
|
||||
$deployment->setAttribute('status', 'ready');
|
||||
$deployment->setAttribute('buildPath', $response['path']);
|
||||
$deployment->setAttribute('buildSize', $response['size']);
|
||||
$deployment->setAttribute('totalSize', $deployment->getAttribute('buildSize', 0) + $deployment->getAttribute('sourceSize', 0));
|
||||
|
||||
$logs = '';
|
||||
foreach ($response['output'] as $log) {
|
||||
$logs .= $log['content'];
|
||||
}
|
||||
$logs .= "[37mCapturing screenshots ...[0m\n";
|
||||
$deployment->setAttribute('buildLogs', $logs);
|
||||
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
if ($isVcsEnabled) {
|
||||
$this->runGitAction('ready', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform);
|
||||
}
|
||||
|
||||
Console::success("Build id: $deploymentId created");
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
/** Screenshot site */
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
try {
|
||||
$rule = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
|
||||
@@ -772,75 +840,96 @@ class Builds extends Action
|
||||
'bannerDisabled' => true,
|
||||
'projectCheckDisabled' => true,
|
||||
'previewAuthDisabled' => true,
|
||||
'deploymentStatusIgnored' => true
|
||||
]);
|
||||
|
||||
// TODO: @Meldiron if becomes too slow, do concurrently
|
||||
foreach ($configs as $key => $config) {
|
||||
$config['headers'] = \array_merge($config['headers'] ?? [], [
|
||||
'x-appwrite-key' => API_KEY_DYNAMIC . '_' . $apiKey
|
||||
]);
|
||||
$screenshotError = null;
|
||||
$screenshots = batch(\array_map(function ($key) use ($configs, $deviceForFiles, $apiKey, $resource, $client, $bucket, $project, $dbForPlatform, &$screenshotError) {
|
||||
return function () use ($key, $configs, $deviceForFiles, $apiKey, $resource, $client, $bucket, $project, $dbForPlatform, &$screenshotError) {
|
||||
try {
|
||||
$config = $configs[$key];
|
||||
|
||||
$config['sleep'] = 3000; // 3 seconds
|
||||
$config['headers'] = \array_merge($config['headers'] ?? [], [
|
||||
'x-appwrite-key' => API_KEY_DYNAMIC . '_' . $apiKey
|
||||
]);
|
||||
$config['sleep'] = 3000;
|
||||
|
||||
// Makes tests much faster
|
||||
$isDevelopment = System::getEnv('_APP_ENV', 'development') === 'development';
|
||||
if ($isDevelopment) {
|
||||
$config['sleep'] = 0; // Override this when running Screenshot.php task
|
||||
}
|
||||
$frameworks = Config::getParam('frameworks', []);
|
||||
$framework = $frameworks[$resource->getAttribute('framework', '')] ?? null;
|
||||
if (!is_null($framework)) {
|
||||
$config['sleep'] = $framework['screenshotSleep'];
|
||||
}
|
||||
|
||||
$response = $client->fetch(
|
||||
url: 'http://appwrite-browser:3000/v1/screenshots',
|
||||
method: 'POST',
|
||||
body: $config
|
||||
);
|
||||
$fetchResponse = $client->fetch(
|
||||
url: 'http://appwrite-browser:3000/v1/screenshots',
|
||||
method: 'POST',
|
||||
body: $config
|
||||
);
|
||||
|
||||
if ($response->getStatusCode() >= 400) {
|
||||
throw new \Exception($response->getBody());
|
||||
}
|
||||
if ($fetchResponse->getStatusCode() >= 400) {
|
||||
throw new \Exception($fetchResponse->getBody());
|
||||
}
|
||||
|
||||
$screenshot = $response->getBody();
|
||||
$screenshot = $fetchResponse->getBody();
|
||||
|
||||
$fileId = ID::unique();
|
||||
$fileName = $fileId . '.png';
|
||||
$path = $deviceForFiles->getPath($fileName);
|
||||
$path = str_ireplace($deviceForFiles->getRoot(), $deviceForFiles->getRoot() . DIRECTORY_SEPARATOR . $bucket->getId(), $path); // Add bucket id to path after root
|
||||
$success = $deviceForFiles->write($path, $screenshot, "image/png");
|
||||
$fileId = ID::unique();
|
||||
$fileName = $fileId . '.png';
|
||||
$path = $deviceForFiles->getPath($fileName);
|
||||
$path = str_ireplace($deviceForFiles->getRoot(), $deviceForFiles->getRoot() . DIRECTORY_SEPARATOR . $bucket->getId(), $path); // Add bucket id to path after root
|
||||
$success = $deviceForFiles->write($path, $screenshot, "image/png");
|
||||
|
||||
if (!$success) {
|
||||
throw new \Exception("Screenshot failed to save");
|
||||
}
|
||||
if (!$success) {
|
||||
throw new \Exception("Screenshot failed to save");
|
||||
}
|
||||
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
$file = new Document([
|
||||
'$id' => $fileId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::team(ID::custom($teamId))),
|
||||
],
|
||||
'bucketId' => $bucket->getId(),
|
||||
'bucketInternalId' => $bucket->getInternalId(),
|
||||
'name' => $fileName,
|
||||
'path' => $path,
|
||||
'signature' => $deviceForFiles->getFileHash($path),
|
||||
'mimeType' => $deviceForFiles->getFileMimeType($path),
|
||||
'sizeOriginal' => \strlen($screenshot),
|
||||
'sizeActual' => $deviceForFiles->getFileSize($path),
|
||||
'algorithm' => Compression::GZIP,
|
||||
'comment' => '',
|
||||
'chunksTotal' => 1,
|
||||
'chunksUploaded' => 1,
|
||||
'openSSLVersion' => null,
|
||||
'openSSLCipher' => null,
|
||||
'openSSLTag' => null,
|
||||
'openSSLIV' => null,
|
||||
'search' => implode(' ', [$fileId, $fileName]),
|
||||
'metadata' => ['content_type' => $deviceForFiles->getFileMimeType($path)],
|
||||
]);
|
||||
$file = Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file));
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
$file = new Document([
|
||||
'$id' => $fileId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::team(ID::custom($teamId))),
|
||||
],
|
||||
'bucketId' => $bucket->getId(),
|
||||
'bucketInternalId' => $bucket->getInternalId(),
|
||||
'name' => $fileName,
|
||||
'path' => $path,
|
||||
'signature' => $deviceForFiles->getFileHash($path),
|
||||
'mimeType' => $deviceForFiles->getFileMimeType($path),
|
||||
'sizeOriginal' => \strlen($screenshot),
|
||||
'sizeActual' => $deviceForFiles->getFileSize($path),
|
||||
'algorithm' => Compression::GZIP,
|
||||
'comment' => '',
|
||||
'chunksTotal' => 1,
|
||||
'chunksUploaded' => 1,
|
||||
'openSSLVersion' => null,
|
||||
'openSSLCipher' => null,
|
||||
'openSSLTag' => null,
|
||||
'openSSLIV' => null,
|
||||
'search' => implode(' ', [$fileId, $fileName]),
|
||||
'metadata' => ['content_type' => $deviceForFiles->getFileMimeType($path)],
|
||||
]);
|
||||
$file = Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file));
|
||||
|
||||
$deployment->setAttribute($key, $fileId);
|
||||
return [ 'key' => $key, 'fileId' => $fileId ];
|
||||
} catch (\Throwable $th) {
|
||||
$screenshotError = $th->getMessage();
|
||||
return;
|
||||
}
|
||||
};
|
||||
}, \array_keys($configs)));
|
||||
|
||||
if (!\is_null($screenshotError)) {
|
||||
throw new \Exception($screenshotError);
|
||||
}
|
||||
|
||||
foreach ($screenshots as $screenshot) {
|
||||
$deployment->setAttribute($screenshot['key'], $screenshot['fileId']);
|
||||
}
|
||||
|
||||
$dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Screenshot failed to generate:");
|
||||
Console::warning($th->getMessage());
|
||||
@@ -848,6 +937,25 @@ class Builds extends Action
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the status */
|
||||
$deployment->setAttribute('status', 'ready');
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
|
||||
|
||||
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
|
||||
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
if ($isVcsEnabled) {
|
||||
$this->runGitAction('ready', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform);
|
||||
}
|
||||
|
||||
Console::success("Build id: $deploymentId created");
|
||||
|
||||
/** Set auto deploy */
|
||||
if ($deployment->getAttribute('activate') === true) {
|
||||
$resource->setAttribute('live', true);
|
||||
@@ -857,6 +965,7 @@ class Builds extends Action
|
||||
|
||||
$resource->setAttribute('deploymentId', $deployment->getId());
|
||||
$resource->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
$resource->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
|
||||
$resource = $dbForProject->updateDocument('functions', $resource->getId(), $resource);
|
||||
|
||||
$queries = [
|
||||
@@ -873,7 +982,9 @@ class Builds extends Action
|
||||
$queries[] = Query::equal("deploymentInternalId", [$oldDeploymentInternalId]);
|
||||
}
|
||||
|
||||
$this->listRules($project, $queries, $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment) {
|
||||
$rulesUpdated = false;
|
||||
$this->listRules($project, $queries, $dbForPlatform, function (Document $rule) use ($dbForPlatform, $deployment, &$rulesUpdated) {
|
||||
$rulesUpdated = true;
|
||||
$rule = $rule
|
||||
->setAttribute('deploymentId', $deployment->getId())
|
||||
->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
@@ -885,8 +996,10 @@ class Builds extends Action
|
||||
|
||||
$resource->setAttribute('deploymentId', $deployment->getId());
|
||||
$resource->setAttribute('deploymentInternalId', $deployment->getInternalId());
|
||||
$resource->setAttribute('deploymentScreenshotDark', $deployment->getAttribute('screenshotDark', ''));
|
||||
$resource->setAttribute('deploymentScreenshotLight', $deployment->getAttribute('screenshotLight', ''));
|
||||
$resource->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
|
||||
$resource = $dbForProject->updateDocument('sites', $resource->getId(), $resource);
|
||||
|
||||
$queries = [
|
||||
Query::equal("projectInternalId", [$project->getInternalId()]),
|
||||
Query::equal("type", ["deployment"]),
|
||||
@@ -937,6 +1050,8 @@ class Builds extends Action
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]));
|
||||
} catch (Duplicate $err) {
|
||||
$rule = $dbForPlatform->getDocument('rules', $ruleId);
|
||||
@@ -979,6 +1094,12 @@ class Builds extends Action
|
||||
Authorization::skip(fn () => $dbForPlatform->updateDocument('schedules', $schedule->getId(), $schedule));
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Build failed:');
|
||||
Console::error($th->getMessage());
|
||||
Console::error($th->getFile());
|
||||
Console::error($th->getLine());
|
||||
Console::error($th->getTraceAsString());
|
||||
|
||||
if ($dbForProject->getDocument('deployments', $deploymentId)->getAttribute('status') === 'canceled') {
|
||||
Console::info('Build has been canceled');
|
||||
return;
|
||||
@@ -999,19 +1120,20 @@ class Builds extends Action
|
||||
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment);
|
||||
|
||||
if ($deployment->getInternalId() === $resource->getAttribute('latestDeploymentInternalId', '')) {
|
||||
$resource = $resource->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource);
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
if ($isVcsEnabled) {
|
||||
$this->runGitAction('failed', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform);
|
||||
}
|
||||
} finally {
|
||||
/**
|
||||
* Trigger Realtime Event
|
||||
*/
|
||||
$queueForRealtime
|
||||
->setSubscribers(['console'])
|
||||
->setProject($project)
|
||||
->setEvent($event)
|
||||
->setParam($resourceKey, $resource->getId())
|
||||
->setParam('deploymentId', $deployment->getId())
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
@@ -1156,8 +1278,18 @@ class Builds extends Action
|
||||
* @throws Conflict
|
||||
* @throws Restricted
|
||||
*/
|
||||
protected function runGitAction(string $status, GitHub $github, string $providerCommitHash, string $owner, string $repositoryName, Document $project, Document $resource, string $deploymentId, Database $dbForProject, Database $dbForPlatform): void
|
||||
{
|
||||
protected function runGitAction(
|
||||
string $status,
|
||||
GitHub $github,
|
||||
string $providerCommitHash,
|
||||
string $owner,
|
||||
string $repositoryName,
|
||||
Document $project,
|
||||
Document $resource,
|
||||
string $deploymentId,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform
|
||||
): void {
|
||||
if ($resource->getAttribute('providerSilentMode', false) === true) {
|
||||
return;
|
||||
}
|
||||
@@ -1187,7 +1319,14 @@ class Builds extends Action
|
||||
|
||||
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https';
|
||||
$hostname = System::getEnv('_APP_DOMAIN');
|
||||
$providerTargetUrl = "{$protocol}://{$hostname}/console/project-{$project->getId()}/functions/function-{$resource->getId()}";
|
||||
|
||||
$projectId = $project->getId();
|
||||
$resourceId = $resource->getId();
|
||||
$providerTargetUrl = match ($resource->getCollection()) {
|
||||
'functions' => "{$protocol}://{$hostname}/console/project-{$projectId}/functions/function-{$resourceId}",
|
||||
'sites' => "{$protocol}://{$hostname}/console/project-{$projectId}/sites/site-{$resourceId}",
|
||||
default => throw new \Exception('Invalid resource type')
|
||||
};
|
||||
|
||||
$github->updateCommitStatus($repositoryName, $providerCommitHash, $owner, $state, $message, $providerTargetUrl, $name);
|
||||
}
|
||||
|
||||
@@ -117,6 +117,14 @@ class Create extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$owner = '';
|
||||
if (
|
||||
($functionsDomain != '' && \str_ends_with($domain->get(), $functionsDomain)) ||
|
||||
($sitesDomain != '' && \str_ends_with($domain->get(), $sitesDomain))
|
||||
) {
|
||||
$owner = 'Appwrite';
|
||||
}
|
||||
|
||||
$rule = new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -127,6 +135,8 @@ class Create extends Action
|
||||
'trigger' => 'manual',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain->get()]),
|
||||
'owner' => $owner,
|
||||
'region' => $project->getAttribute('region')
|
||||
]);
|
||||
|
||||
try {
|
||||
|
||||
@@ -125,6 +125,14 @@ class Create extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$owner = '';
|
||||
if (
|
||||
($functionsDomain != '' && \str_ends_with($domain->get(), $functionsDomain)) ||
|
||||
($sitesDomain != '' && \str_ends_with($domain->get(), $sitesDomain))
|
||||
) {
|
||||
$owner = 'Appwrite';
|
||||
}
|
||||
|
||||
$rule = new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -141,6 +149,8 @@ class Create extends Action
|
||||
'deploymentVcsProviderBranch' => $branch,
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain->get(), $branch]),
|
||||
'owner' => $owner,
|
||||
'region' => $project->getAttribute('region')
|
||||
]);
|
||||
|
||||
try {
|
||||
|
||||
@@ -117,6 +117,14 @@ class Create extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$owner = '';
|
||||
if (
|
||||
($functionsDomain != '' && \str_ends_with($domain->get(), $functionsDomain)) ||
|
||||
($sitesDomain != '' && \str_ends_with($domain->get(), $sitesDomain))
|
||||
) {
|
||||
$owner = 'Appwrite';
|
||||
}
|
||||
|
||||
$rule = new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -129,6 +137,8 @@ class Create extends Action
|
||||
'redirectStatusCode' => $statusCode,
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain->get()]),
|
||||
'owner' => $owner,
|
||||
'region' => $project->getAttribute('region')
|
||||
]);
|
||||
|
||||
try {
|
||||
|
||||
@@ -125,6 +125,14 @@ class Create extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$owner = '';
|
||||
if (
|
||||
($functionsDomain != '' && \str_ends_with($domain->get(), $functionsDomain)) ||
|
||||
($sitesDomain != '' && \str_ends_with($domain->get(), $sitesDomain))
|
||||
) {
|
||||
$owner = 'Appwrite';
|
||||
}
|
||||
|
||||
$rule = new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -141,6 +149,8 @@ class Create extends Action
|
||||
'deploymentVcsProviderBranch' => $branch,
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain->get(), $branch]),
|
||||
'owner' => $owner,
|
||||
'region' => $project->getAttribute('region')
|
||||
]);
|
||||
|
||||
try {
|
||||
|
||||
@@ -241,14 +241,24 @@ class Create extends Action
|
||||
'resourceType' => 'sites',
|
||||
'buildCommands' => \implode(' && ', $commands),
|
||||
'buildOutput' => $outputDirectory,
|
||||
'adapter' => $site->getAttribute('adapter', ''),
|
||||
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
|
||||
'sourcePath' => $path,
|
||||
'sourceSize' => $fileSize,
|
||||
'totalSize' => $fileSize,
|
||||
'search' => implode(' ', [$deploymentId]),
|
||||
'activate' => $activate,
|
||||
'sourceMetadata' => $metadata,
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
]));
|
||||
|
||||
$site = $site
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('sites', $site->getId(), $site);
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$domain = ID::unique() . "." . $sitesDomain;
|
||||
|
||||
@@ -271,6 +281,8 @@ class Create extends Action
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
} else {
|
||||
@@ -296,16 +308,26 @@ class Create extends Action
|
||||
'resourceType' => 'sites',
|
||||
'buildCommands' => \implode(' && ', $commands),
|
||||
'buildOutput' => $outputDirectory,
|
||||
'adapter' => $site->getAttribute('adapter', ''),
|
||||
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
|
||||
'sourcePath' => $path,
|
||||
'sourceSize' => $fileSize,
|
||||
'totalSize' => $fileSize,
|
||||
'sourceChunksTotal' => $chunks,
|
||||
'sourceChunksUploaded' => $chunksUploaded,
|
||||
'search' => implode(' ', [$deploymentId]),
|
||||
'activate' => $activate,
|
||||
'sourceMetadata' => $metadata,
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
]));
|
||||
|
||||
$site = $site
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('sites', $site->getId(), $site);
|
||||
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$domain = ID::unique() . "." . $sitesDomain;
|
||||
$ruleId = md5($domain);
|
||||
|
||||
@@ -12,6 +12,7 @@ use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
@@ -96,10 +97,30 @@ class Delete extends Action
|
||||
}
|
||||
}
|
||||
|
||||
if ($site->getAttribute('latestDeploymentId') === $deployment->getId()) {
|
||||
$latestDeployment = $dbForProject->findOne('deployments', [
|
||||
Query::equal('resourceType', ['sites']),
|
||||
Query::equal('resourceInternalId', [$site->getInternalId()]),
|
||||
Query::orderDesc('$createdAt'),
|
||||
]);
|
||||
$site = $dbForProject->updateDocument(
|
||||
'sites',
|
||||
$site->getId(),
|
||||
$site
|
||||
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->isEmpty() ? '' : $latestDeployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getInternalId())
|
||||
->setAttribute('latestDeploymentId', $latestDeployment->isEmpty() ? '' : $latestDeployment->getId())
|
||||
->setAttribute('latestDeploymentStatus', $latestDeployment->isEmpty() ? '' : $latestDeployment->getAttribute('status', ''))
|
||||
);
|
||||
}
|
||||
|
||||
if ($site->getAttribute('deploymentId') === $deployment->getId()) { // Reset site deployment
|
||||
$site = $dbForProject->updateDocument('sites', $site->getId(), new Document(array_merge($site->getArrayCopy(), [
|
||||
'deploymentId' => '',
|
||||
'deploymentInternalId' => '',
|
||||
'deploymentScreenshotDark' => '',
|
||||
'deploymentScreenshotLight' => '',
|
||||
'deploymentCreatedAt' => '',
|
||||
])));
|
||||
}
|
||||
|
||||
|
||||
@@ -111,20 +111,30 @@ class Create extends Action
|
||||
'$internalId' => '',
|
||||
'$id' => $deploymentId,
|
||||
'sourcePath' => $destination,
|
||||
'totalSize' => $deployment->getAttribute('sourceSize', 0),
|
||||
'buildCommands' => \implode(' && ', $commands),
|
||||
'buildOutput' => $site->getAttribute('outputDirectory', ''),
|
||||
'adapter' => $site->getAttribute('adapter', ''),
|
||||
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
|
||||
'search' => implode(' ', [$deploymentId]),
|
||||
'screenshotLight' => '',
|
||||
'screenshotDark' => '',
|
||||
'buildStartAt' => null,
|
||||
'buildEndAt' => null,
|
||||
'buildDuration' => null,
|
||||
'buildSize' => null,
|
||||
'buildDuration' => 0,
|
||||
'buildSize' => 0,
|
||||
'status' => 'waiting',
|
||||
'buildPath' => '',
|
||||
'buildLogs' => '',
|
||||
]));
|
||||
|
||||
$site = $site
|
||||
->setAttribute('latestDeploymentId', $deployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('sites', $site->getId(), $site);
|
||||
|
||||
// Preview deployments for sites
|
||||
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
|
||||
$domain = ID::unique() . "." . $sitesDomain;
|
||||
@@ -148,6 +158,8 @@ class Create extends Action
|
||||
'status' => 'verified',
|
||||
'certificateId' => '',
|
||||
'search' => implode(' ', [$ruleId, $domain]),
|
||||
'owner' => 'Appwrite',
|
||||
'region' => $project->getAttribute('region')
|
||||
]))
|
||||
);
|
||||
|
||||
|
||||
@@ -93,6 +93,11 @@ class Update extends Action
|
||||
'status' => 'canceled'
|
||||
]));
|
||||
|
||||
if ($deployment->getInternalId() === $site->getAttribute('latestDeploymentInternalId', '')) {
|
||||
$site = $site->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$dbForProject->updateDocument('sites', $site->getId(), $site);
|
||||
}
|
||||
|
||||
try {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
$executor->deleteRuntime($project->getId(), $deploymentId . "-build");
|
||||
|
||||