Merge branch 'feat-sites' into chore-add-tests-for-empty-output-dir
8
.env
|
|
@ -23,7 +23,9 @@ _APP_OPENSSL_KEY_V1=your-secret-key
|
|||
_APP_DOMAIN=traefik
|
||||
_APP_DOMAIN_FUNCTIONS=functions.localhost
|
||||
_APP_DOMAIN_SITES=sites.localhost
|
||||
_APP_DOMAIN_TARGET=test.appwrite.io
|
||||
_APP_DOMAIN_TARGET_CNAME=test.appwrite.io
|
||||
_APP_DOMAIN_TARGET_A=127.0.0.1
|
||||
_APP_DOMAIN_TARGET_AAAA=::1
|
||||
_APP_RULES_FORMAT=md5
|
||||
_APP_REDIS_HOST=redis
|
||||
_APP_REDIS_PORT=6379
|
||||
|
|
@ -71,7 +73,8 @@ _APP_SMS_PROJECTS_DENY_LIST=
|
|||
_APP_STORAGE_LIMIT=30000000
|
||||
_APP_STORAGE_PREVIEW_LIMIT=20000000
|
||||
_APP_COMPUTE_SIZE_LIMIT=30000000
|
||||
_APP_COMPUTE_TIMEOUT=900
|
||||
_APP_FUNCTIONS_TIMEOUT=900
|
||||
_APP_SITES_TIMEOUT=30
|
||||
_APP_COMPUTE_BUILD_TIMEOUT=900
|
||||
_APP_COMPUTE_CPUS=8
|
||||
_APP_COMPUTE_MEMORY=8192
|
||||
|
|
@ -88,6 +91,7 @@ _APP_MAINTENANCE_RETENTION_CACHE=2592000
|
|||
_APP_MAINTENANCE_RETENTION_EXECUTION=1209600
|
||||
_APP_MAINTENANCE_RETENTION_ABUSE=86400
|
||||
_APP_MAINTENANCE_RETENTION_AUDIT=1209600
|
||||
_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE=15778800
|
||||
_APP_USAGE_AGGREGATION_INTERVAL=30
|
||||
_APP_STATS_RESOURCES_INTERVAL=3600
|
||||
_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ tasks:
|
|||
docker pull composer
|
||||
command: |
|
||||
docker run --rm --interactive --tty \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
--volume $PWD:/app \
|
||||
composer install \
|
||||
--ignore-platform-reqs \
|
||||
|
|
@ -23,11 +24,3 @@ vscode:
|
|||
extensions:
|
||||
- ms-azuretools.vscode-docker
|
||||
- zobo.php-intellisense
|
||||
|
||||
github:
|
||||
# https://www.gitpod.io/docs/prebuilds#github-specific-configuration
|
||||
prebuilds:
|
||||
# enable for pull requests coming from forks (defaults to false)
|
||||
pullRequestsFromForks: true
|
||||
# add a check to pull requests (defaults to true)
|
||||
addCheck: false
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use Appwrite\Event\StatsResources;
|
|||
use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Platform\Appwrite;
|
||||
use Appwrite\Runtimes\Runtimes;
|
||||
use Executor\Executor;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\CLI\CLI;
|
||||
|
|
@ -255,6 +256,8 @@ CLI::setResource('logError', function (Registry $register) {
|
|||
};
|
||||
}, ['register']);
|
||||
|
||||
CLI::setResource('executor', fn () => new Executor(fn (string $projectId, string $deploymentId) => System::getEnv('_APP_EXECUTOR_HOST')));
|
||||
|
||||
$platform = new Appwrite();
|
||||
$platform->init(Service::TYPE_TASK);
|
||||
|
||||
|
|
|
|||
|
|
@ -1038,7 +1038,7 @@ return [
|
|||
'$id' => ID::custom('providerUid'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 2048,
|
||||
'size' => 2048, // Decrease to 128 as in index length?
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
|
|
@ -1107,14 +1107,14 @@ return [
|
|||
'$id' => ID::custom('_key_userInternalId_provider_providerUid'),
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['userInternalId', 'provider', 'providerUid'],
|
||||
'lengths' => [11, 128, 128],
|
||||
'lengths' => [11, 128, 128], // providerUid is length 2000!
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_provider_providerUid'),
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['provider', 'providerUid'],
|
||||
'lengths' => [128, 128],
|
||||
'lengths' => [128, 128], // providerUid is length 2000!
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
|
@ -1417,6 +1417,13 @@ return [
|
|||
'lengths' => [],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_roles'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['roles'],
|
||||
'lengths' => [128],
|
||||
'orders' => [],
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -971,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,
|
||||
|
|
@ -1725,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' => [
|
||||
|
|
|
|||
|
|
@ -580,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 => [
|
||||
|
|
@ -832,7 +837,7 @@ return [
|
|||
Exception::RULE_VERIFICATION_FAILED => [
|
||||
'name' => Exception::RULE_VERIFICATION_FAILED,
|
||||
'description' => 'Domain verification failed. Please check if your DNS records are correct and try again.',
|
||||
'code' => 401,
|
||||
'code' => 400,
|
||||
'publish' => true
|
||||
],
|
||||
Exception::PROJECT_SMTP_CONFIG_INVALID => [
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -30,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'
|
||||
]
|
||||
]
|
||||
|
|
@ -48,7 +48,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -56,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'
|
||||
]
|
||||
]
|
||||
|
|
@ -74,7 +74,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -82,14 +82,14 @@ 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',
|
||||
]
|
||||
]
|
||||
],
|
||||
|
|
@ -105,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'
|
||||
]
|
||||
]
|
||||
|
|
@ -116,7 +116,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -124,21 +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' => 3000,
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'adapters' => [
|
||||
|
|
@ -147,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'
|
||||
]
|
||||
]
|
||||
|
|
@ -158,7 +158,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -166,14 +166,14 @@ 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',
|
||||
]
|
||||
]
|
||||
],
|
||||
|
|
@ -183,7 +183,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -191,14 +191,14 @@ 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',
|
||||
]
|
||||
]
|
||||
],
|
||||
|
|
@ -208,7 +208,7 @@ return [
|
|||
'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' => [
|
||||
|
|
@ -216,14 +216,31 @@ 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',
|
||||
]
|
||||
]
|
||||
],
|
||||
'lynx' => [
|
||||
'key' => 'lynx',
|
||||
'name' => 'Lynx',
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
'fallbackFile' => 'index.html'
|
||||
]
|
||||
]
|
||||
],
|
||||
|
|
@ -239,7 +256,7 @@ return [
|
|||
'buildCommand' => 'flutter build web',
|
||||
'installCommand' => '',
|
||||
'outputDirectory' => './build/web',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
|
@ -255,7 +272,7 @@ return [
|
|||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
],
|
||||
]
|
||||
],
|
||||
|
|
@ -271,7 +288,7 @@ return [
|
|||
'buildCommand' => '',
|
||||
'installCommand' => '',
|
||||
'outputDirectory' => './',
|
||||
'startCommand' => 'sh helpers/server.sh',
|
||||
'startCommand' => 'bash helpers/server.sh',
|
||||
],
|
||||
]
|
||||
],
|
||||
|
|
|
|||
9612
app/config/specs/open-api3-1.7.x-client.json
Normal file
41627
app/config/specs/open-api3-1.7.x-console.json
Normal file
29170
app/config/specs/open-api3-1.7.x-server.json
Normal file
|
|
@ -6848,7 +6848,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: userId, teamId, invited, joined, confirm",
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
@ -9362,7 +9362,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "functions.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -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": {
|
||||
|
|
@ -24718,6 +24718,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -24730,6 +24731,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.",
|
||||
|
|
@ -24912,7 +24918,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "sites.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -25348,6 +25354,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -25360,6 +25367,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.",
|
||||
|
|
@ -25902,7 +25914,7 @@
|
|||
},
|
||||
"\/sites\/{siteId}\/deployments\/template": {
|
||||
"post": {
|
||||
"summary": "Create deployment",
|
||||
"summary": "Create template deployment",
|
||||
"operationId": "sitesCreateTemplateDeployment",
|
||||
"tags": [
|
||||
"sites"
|
||||
|
|
@ -28883,7 +28895,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: userId, teamId, invited, joined, confirm",
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
|
|
@ -30976,6 +30988,30 @@
|
|||
"x-example": "<USER_ID>"
|
||||
},
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"description": "Search term to filter your list results. Max length: 256 chars.",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<SEARCH>",
|
||||
"default": ""
|
||||
},
|
||||
"in": "query"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -36864,6 +36900,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.",
|
||||
|
|
@ -36986,6 +37027,7 @@
|
|||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
|
|
@ -37024,6 +37066,11 @@
|
|||
"description": "Site Template Name.",
|
||||
"x-example": "Starter site"
|
||||
},
|
||||
"tagline": {
|
||||
"type": "string",
|
||||
"description": "Short description of template",
|
||||
"x-example": "Minimal web app integrating with Appwrite."
|
||||
},
|
||||
"demoUrl": {
|
||||
"type": "string",
|
||||
"description": "URL hosting a template demo.",
|
||||
|
|
@ -37087,6 +37134,7 @@
|
|||
"required": [
|
||||
"key",
|
||||
"name",
|
||||
"tagline",
|
||||
"demoUrl",
|
||||
"screenshotDark",
|
||||
"screenshotLight",
|
||||
|
|
@ -37205,7 +37253,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": {
|
||||
|
|
@ -40824,11 +40872,21 @@
|
|||
"description": "Console Variables",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_APP_DOMAIN_TARGET": {
|
||||
"_APP_DOMAIN_TARGET_CNAME": {
|
||||
"type": "string",
|
||||
"description": "CNAME target for your Appwrite custom domains.",
|
||||
"x-example": "appwrite.io"
|
||||
},
|
||||
"_APP_DOMAIN_TARGET_A": {
|
||||
"type": "string",
|
||||
"description": "A target for your Appwrite custom domains.",
|
||||
"x-example": "127.0.0.1"
|
||||
},
|
||||
"_APP_DOMAIN_TARGET_AAAA": {
|
||||
"type": "string",
|
||||
"description": "AAAA target for your Appwrite custom domains.",
|
||||
"x-example": "::1"
|
||||
},
|
||||
"_APP_STORAGE_LIMIT": {
|
||||
"type": "integer",
|
||||
"description": "Maximum file size allowed for file upload in bytes.",
|
||||
|
|
@ -40866,6 +40924,11 @@
|
|||
"description": "A domain to use for site URLs.",
|
||||
"x-example": "sites.localhost"
|
||||
},
|
||||
"_APP_DOMAIN_FUNCTIONS": {
|
||||
"type": "string",
|
||||
"description": "A domain to use for function URLs.",
|
||||
"x-example": "functions.localhost"
|
||||
},
|
||||
"_APP_OPTIONS_FORCE_HTTPS": {
|
||||
"type": "string",
|
||||
"description": "Defines if HTTPS is enforced for all requests.",
|
||||
|
|
@ -40878,7 +40941,9 @@
|
|||
}
|
||||
},
|
||||
"required": [
|
||||
"_APP_DOMAIN_TARGET",
|
||||
"_APP_DOMAIN_TARGET_CNAME",
|
||||
"_APP_DOMAIN_TARGET_A",
|
||||
"_APP_DOMAIN_TARGET_AAAA",
|
||||
"_APP_STORAGE_LIMIT",
|
||||
"_APP_COMPUTE_SIZE_LIMIT",
|
||||
"_APP_USAGE_STATS",
|
||||
|
|
@ -40886,6 +40951,7 @@
|
|||
"_APP_DOMAIN_ENABLED",
|
||||
"_APP_ASSISTANT_ENABLED",
|
||||
"_APP_DOMAIN_SITES",
|
||||
"_APP_DOMAIN_FUNCTIONS",
|
||||
"_APP_OPTIONS_FORCE_HTTPS",
|
||||
"_APP_DOMAINS_NAMESERVERS"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
@ -8449,7 +8449,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "functions.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -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": {
|
||||
|
|
@ -16816,6 +16816,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -16828,6 +16829,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.",
|
||||
|
|
@ -17010,7 +17016,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "sites.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -17221,6 +17227,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -17233,6 +17240,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.",
|
||||
|
|
@ -17780,7 +17792,7 @@
|
|||
},
|
||||
"\/sites\/{siteId}\/deployments\/template": {
|
||||
"post": {
|
||||
"summary": "Create deployment",
|
||||
"summary": "Create template deployment",
|
||||
"operationId": "sitesCreateTemplateDeployment",
|
||||
"tags": [
|
||||
"sites"
|
||||
|
|
@ -20503,7 +20515,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: userId, teamId, invited, joined, confirm",
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
|
|
@ -22557,6 +22569,30 @@
|
|||
"x-example": "<USER_ID>"
|
||||
},
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"description": "Search term to filter your list results. Max length: 256 chars.",
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<SEARCH>",
|
||||
"default": ""
|
||||
},
|
||||
"in": "query"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -27413,6 +27449,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.",
|
||||
|
|
@ -27535,6 +27576,7 @@
|
|||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
|
|
@ -27603,7 +27645,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": {
|
||||
|
|
|
|||
9771
app/config/specs/swagger2-1.7.x-client.json
Normal file
42246
app/config/specs/swagger2-1.7.x-console.json
Normal file
29680
app/config/specs/swagger2-1.7.x-server.json
Normal file
|
|
@ -7060,7 +7060,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: userId, teamId, invited, joined, confirm",
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
},
|
||||
|
|
@ -9530,7 +9530,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "functions.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -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
|
||||
},
|
||||
|
|
@ -25221,6 +25221,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -25234,10 +25235,16 @@
|
|||
"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.",
|
||||
"default": 15,
|
||||
"default": 30,
|
||||
"x-example": 1
|
||||
},
|
||||
"installCommand": {
|
||||
|
|
@ -25430,7 +25437,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "sites.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -25865,6 +25872,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -25878,10 +25886,16 @@
|
|||
"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.",
|
||||
"default": 15,
|
||||
"default": 30,
|
||||
"x-example": 1
|
||||
},
|
||||
"installCommand": {
|
||||
|
|
@ -26428,7 +26442,7 @@
|
|||
},
|
||||
"\/sites\/{siteId}\/deployments\/template": {
|
||||
"post": {
|
||||
"summary": "Create deployment",
|
||||
"summary": "Create template deployment",
|
||||
"operationId": "sitesCreateTemplateDeployment",
|
||||
"consumes": [
|
||||
"application\/json"
|
||||
|
|
@ -29414,7 +29428,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: userId, teamId, invited, joined, confirm",
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
|
|
@ -31557,6 +31571,27 @@
|
|||
"type": "string",
|
||||
"x-example": "<USER_ID>",
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": [],
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"description": "Search term to filter your list results. Max length: 256 chars.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "<SEARCH>",
|
||||
"default": "",
|
||||
"in": "query"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -37444,6 +37479,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.",
|
||||
|
|
@ -37567,6 +37607,7 @@
|
|||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
|
|
@ -37605,6 +37646,11 @@
|
|||
"description": "Site Template Name.",
|
||||
"x-example": "Starter site"
|
||||
},
|
||||
"tagline": {
|
||||
"type": "string",
|
||||
"description": "Short description of template",
|
||||
"x-example": "Minimal web app integrating with Appwrite."
|
||||
},
|
||||
"demoUrl": {
|
||||
"type": "string",
|
||||
"description": "URL hosting a template demo.",
|
||||
|
|
@ -37670,6 +37716,7 @@
|
|||
"required": [
|
||||
"key",
|
||||
"name",
|
||||
"tagline",
|
||||
"demoUrl",
|
||||
"screenshotDark",
|
||||
"screenshotLight",
|
||||
|
|
@ -37788,7 +37835,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": {
|
||||
|
|
@ -41484,11 +41531,21 @@
|
|||
"description": "Console Variables",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"_APP_DOMAIN_TARGET": {
|
||||
"_APP_DOMAIN_TARGET_CNAME": {
|
||||
"type": "string",
|
||||
"description": "CNAME target for your Appwrite custom domains.",
|
||||
"x-example": "appwrite.io"
|
||||
},
|
||||
"_APP_DOMAIN_TARGET_A": {
|
||||
"type": "string",
|
||||
"description": "A target for your Appwrite custom domains.",
|
||||
"x-example": "127.0.0.1"
|
||||
},
|
||||
"_APP_DOMAIN_TARGET_AAAA": {
|
||||
"type": "string",
|
||||
"description": "AAAA target for your Appwrite custom domains.",
|
||||
"x-example": "::1"
|
||||
},
|
||||
"_APP_STORAGE_LIMIT": {
|
||||
"type": "integer",
|
||||
"description": "Maximum file size allowed for file upload in bytes.",
|
||||
|
|
@ -41526,6 +41583,11 @@
|
|||
"description": "A domain to use for site URLs.",
|
||||
"x-example": "sites.localhost"
|
||||
},
|
||||
"_APP_DOMAIN_FUNCTIONS": {
|
||||
"type": "string",
|
||||
"description": "A domain to use for function URLs.",
|
||||
"x-example": "functions.localhost"
|
||||
},
|
||||
"_APP_OPTIONS_FORCE_HTTPS": {
|
||||
"type": "string",
|
||||
"description": "Defines if HTTPS is enforced for all requests.",
|
||||
|
|
@ -41538,7 +41600,9 @@
|
|||
}
|
||||
},
|
||||
"required": [
|
||||
"_APP_DOMAIN_TARGET",
|
||||
"_APP_DOMAIN_TARGET_CNAME",
|
||||
"_APP_DOMAIN_TARGET_A",
|
||||
"_APP_DOMAIN_TARGET_AAAA",
|
||||
"_APP_STORAGE_LIMIT",
|
||||
"_APP_COMPUTE_SIZE_LIMIT",
|
||||
"_APP_USAGE_STATS",
|
||||
|
|
@ -41546,6 +41610,7 @@
|
|||
"_APP_DOMAIN_ENABLED",
|
||||
"_APP_ASSISTANT_ENABLED",
|
||||
"_APP_DOMAIN_SITES",
|
||||
"_APP_DOMAIN_FUNCTIONS",
|
||||
"_APP_OPTIONS_FORCE_HTTPS",
|
||||
"_APP_DOMAINS_NAMESERVERS"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
},
|
||||
|
|
@ -8614,7 +8614,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "functions.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -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
|
||||
},
|
||||
|
|
@ -17285,6 +17285,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -17298,10 +17299,16 @@
|
|||
"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.",
|
||||
"default": 15,
|
||||
"default": 30,
|
||||
"x-example": 1
|
||||
},
|
||||
"installCommand": {
|
||||
|
|
@ -17494,7 +17501,7 @@
|
|||
"rate-limit": 0,
|
||||
"rate-time": 3600,
|
||||
"rate-key": "url:{url},ip:{ip}",
|
||||
"scope": "sites.read",
|
||||
"scope": "public",
|
||||
"platforms": [
|
||||
"server"
|
||||
],
|
||||
|
|
@ -17708,6 +17715,7 @@
|
|||
"sveltekit",
|
||||
"astro",
|
||||
"remix",
|
||||
"lynx",
|
||||
"flutter",
|
||||
"vite",
|
||||
"other"
|
||||
|
|
@ -17721,10 +17729,16 @@
|
|||
"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.",
|
||||
"default": 15,
|
||||
"default": 30,
|
||||
"x-example": 1
|
||||
},
|
||||
"installCommand": {
|
||||
|
|
@ -18276,7 +18290,7 @@
|
|||
},
|
||||
"\/sites\/{siteId}\/deployments\/template": {
|
||||
"post": {
|
||||
"summary": "Create deployment",
|
||||
"summary": "Create template deployment",
|
||||
"operationId": "sitesCreateTemplateDeployment",
|
||||
"consumes": [
|
||||
"application\/json"
|
||||
|
|
@ -21009,7 +21023,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: userId, teamId, invited, joined, confirm",
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
|
|
@ -23113,6 +23127,27 @@
|
|||
"type": "string",
|
||||
"x-example": "<USER_ID>",
|
||||
"in": "path"
|
||||
},
|
||||
{
|
||||
"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: userId, teamId, invited, joined, confirm, roles",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": [],
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"description": "Search term to filter your list results. Max length: 256 chars.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "<SEARCH>",
|
||||
"default": "",
|
||||
"in": "query"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -27964,6 +27999,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.",
|
||||
|
|
@ -28087,6 +28127,7 @@
|
|||
"name",
|
||||
"enabled",
|
||||
"live",
|
||||
"logging",
|
||||
"framework",
|
||||
"deploymentId",
|
||||
"deploymentCreatedAt",
|
||||
|
|
@ -28155,7 +28196,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": {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ return [
|
|||
'icon' => 'icon-lightning-bolt',
|
||||
'id' => 'starter',
|
||||
'name' => 'Starter function',
|
||||
'score' => 5,
|
||||
'tagline' =>
|
||||
'A simple function to get started. Edit this function to explore endless possibilities with Appwrite Functions.',
|
||||
'permissions' => ['any'],
|
||||
|
|
@ -62,6 +63,7 @@ return [
|
|||
'icon' => 'icon-upstash',
|
||||
'id' => 'query-upstash-vector',
|
||||
'name' => 'Query Upstash Vector',
|
||||
'score' => 4,
|
||||
'tagline' => 'Vector database that stores text embeddings and context retrieval for LLMs',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -106,6 +108,7 @@ return [
|
|||
'icon' => 'icon-redis',
|
||||
'id' => 'query-redis-labs',
|
||||
'name' => 'Query Redis Labs',
|
||||
'score' => 4,
|
||||
'tagline' => 'Key-value database with advanced caching capabilities.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -149,6 +152,7 @@ return [
|
|||
'icon' => 'icon-neo4j',
|
||||
'id' => 'query-neo4j-auradb',
|
||||
'name' => 'Query Neo4j AuraDB',
|
||||
'score' => 4,
|
||||
'tagline' => 'Graph database with focus on relations between data.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -200,6 +204,7 @@ return [
|
|||
'icon' => 'icon-mongodb',
|
||||
'id' => 'query-mongo-atlas',
|
||||
'name' => 'Query MongoDB Atlas',
|
||||
'score' => 4,
|
||||
'tagline' =>
|
||||
'Realtime NoSQL document database with geospecial, graph, search, and vector suport.',
|
||||
'permissions' => ['any'],
|
||||
|
|
@ -237,6 +242,7 @@ return [
|
|||
'icon' => 'icon-neon',
|
||||
'id' => 'query-neon-postgres',
|
||||
'name' => 'Query Neon Postgres',
|
||||
'score' => 4,
|
||||
'tagline' =>
|
||||
'Reliable SQL database with replication, point-in-time recovery, and pgvector support.',
|
||||
'permissions' => ['any'],
|
||||
|
|
@ -305,6 +311,7 @@ return [
|
|||
'icon' => 'icon-open-ai',
|
||||
'id' => 'prompt-chatgpt',
|
||||
'name' => 'Prompt ChatGPT',
|
||||
'score' => 7,
|
||||
'tagline' => 'Ask questions and let OpenAI GPT-3.5-turbo answer.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -366,6 +373,7 @@ return [
|
|||
'icon' => 'icon-discord',
|
||||
'id' => 'discord-command-bot',
|
||||
'name' => 'Discord Command Bot',
|
||||
'score' => 6,
|
||||
'tagline' => 'Simple command using Discord Interactions.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -429,6 +437,7 @@ return [
|
|||
'icon' => 'icon-perspective-api',
|
||||
'id' => 'analyze-with-perspectiveapi',
|
||||
'name' => 'Analyze with PerspectiveAPI',
|
||||
'score' => 5,
|
||||
'tagline' => 'Automate moderation by getting toxicity of messages.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -464,6 +473,7 @@ return [
|
|||
'icon' => 'icon-pangea',
|
||||
'id' => 'censor-with-redact',
|
||||
'name' => 'Censor with Redact',
|
||||
'score' => 5,
|
||||
'tagline' =>
|
||||
'Censor sensitive information from a provided text string using Redact API by Pangea.',
|
||||
'permissions' => ['any'],
|
||||
|
|
@ -512,6 +522,7 @@ return [
|
|||
'icon' => 'icon-document',
|
||||
'id' => 'generate-pdf',
|
||||
'name' => 'Generate PDF',
|
||||
'score' => 7,
|
||||
'tagline' => 'Document containing sample invoice in PDF format.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -533,6 +544,7 @@ return [
|
|||
'icon' => 'icon-github',
|
||||
'id' => 'github-issue-bot',
|
||||
'name' => 'GitHub issue bot',
|
||||
'score' => 4,
|
||||
'tagline' =>
|
||||
'Automate the process of responding to newly opened issues in a GitHub repository.',
|
||||
'permissions' => ['any'],
|
||||
|
|
@ -577,6 +589,7 @@ return [
|
|||
'icon' => 'icon-bookmark',
|
||||
'id' => 'url-shortener',
|
||||
'name' => 'URL shortener',
|
||||
'score' => 3,
|
||||
'tagline' => 'Generate URL with short ID and redirect to the original URL when visited.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -628,6 +641,7 @@ return [
|
|||
'icon' => 'icon-algolia',
|
||||
'id' => 'sync-with-algolia',
|
||||
'name' => 'Sync with Algolia',
|
||||
'score' => 4,
|
||||
'tagline' => 'Intuitive search bar for any data in Appwrite Databases.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -709,6 +723,7 @@ return [
|
|||
'icon' => 'icon-meilisearch',
|
||||
'id' => 'sync-with-meilisearch',
|
||||
'name' => 'Sync with Meilisearch',
|
||||
'score' => 4,
|
||||
'tagline' => 'Intuitive search bar for any data in Appwrite Databases.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -802,6 +817,7 @@ return [
|
|||
'icon' => 'icon-vonage',
|
||||
'id' => 'whatsapp-with-vonage',
|
||||
'name' => 'WhatsApp with Vonage',
|
||||
'score' => 6,
|
||||
'tagline' => 'Simple bot to answer WhatsApp messages.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -888,6 +904,7 @@ return [
|
|||
'icon' => 'icon-bell',
|
||||
'id' => 'push-notification-with-fcm',
|
||||
'name' => 'Push notification with FCM',
|
||||
'score' => 4,
|
||||
'tagline' => 'Send push notifications to your users using Firebase Cloud Messaging (FCM).',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -944,6 +961,7 @@ return [
|
|||
'icon' => 'icon-mail',
|
||||
'id' => 'email-contact-form',
|
||||
'name' => 'Email contact form',
|
||||
'score' => 7,
|
||||
'tagline' => 'Sends an email with the contents of a HTML form.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1027,6 +1045,7 @@ return [
|
|||
'icon' => 'icon-stripe',
|
||||
'id' => 'subscriptions-with-stripe',
|
||||
'name' => 'Subscriptions with Stripe',
|
||||
'score' => 6,
|
||||
'tagline' => 'Receive recurring card payments and grant subscribers extra permissions.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1068,6 +1087,7 @@ return [
|
|||
'icon' => 'icon-stripe',
|
||||
'id' => 'payments-with-stripe',
|
||||
'name' => 'Payments with Stripe',
|
||||
'score' => 8,
|
||||
'tagline' => 'Receive card payments and store paid orders.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1125,6 +1145,7 @@ return [
|
|||
'icon' => 'icon-chat',
|
||||
'id' => 'text-generation-with-huggingface',
|
||||
'name' => 'Text generation',
|
||||
'score' => 5,
|
||||
'tagline' => 'Generate text using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1159,6 +1180,7 @@ return [
|
|||
'icon' => 'icon-translate',
|
||||
'id' => 'language-translation-with-huggingface',
|
||||
'name' => 'Language translation',
|
||||
'score' => 5,
|
||||
'tagline' => 'Translate text using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1193,6 +1215,7 @@ return [
|
|||
'icon' => 'icon-eye',
|
||||
'id' => 'image-classification-with-huggingface',
|
||||
'name' => 'Image classification',
|
||||
'score' => 5,
|
||||
'tagline' => 'Classify images using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => ['buckets.*.files.*.create'],
|
||||
|
|
@ -1251,6 +1274,7 @@ return [
|
|||
'icon' => 'icon-eye',
|
||||
'id' => 'object-detection-with-huggingface',
|
||||
'name' => 'Object detection',
|
||||
'score' => 5,
|
||||
'tagline' => 'Detect objects in images using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => ['buckets.*.files.*.create'],
|
||||
|
|
@ -1309,6 +1333,7 @@ return [
|
|||
'icon' => 'icon-text',
|
||||
'id' => 'speech-recognition-with-huggingface',
|
||||
'name' => 'Speech recognition',
|
||||
'score' => 5,
|
||||
'tagline' => 'Transcribe audio to text using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => ['buckets.*.files.*.create'],
|
||||
|
|
@ -1367,6 +1392,7 @@ return [
|
|||
'icon' => 'icon-chat',
|
||||
'id' => 'text-to-speech-with-huggingface',
|
||||
'name' => 'Text to speech',
|
||||
'score' => 5,
|
||||
'tagline' => 'Convert text to speech using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => ['databases.*.collections.*.documents.*.create'],
|
||||
|
|
@ -1425,6 +1451,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'generate-with-replicate',
|
||||
'name' => 'Generate with Replicate',
|
||||
'score' => 5,
|
||||
'tagline' => "Generate text, audio and images using Replicate's API.",
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1460,6 +1487,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'generate-with-together-ai',
|
||||
'name' => 'Generate with Together AI',
|
||||
'score' => 5,
|
||||
'tagline' => "Generate text and images using Together AI's API.",
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1502,6 +1530,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'chat-with-perplexity-ai',
|
||||
'name' => 'Chat with Perplexity AI',
|
||||
'score' => 5,
|
||||
'tagline' => 'Create a chatbot using the Perplexity AI API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1543,6 +1572,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'generate-with-replicate',
|
||||
'name' => 'Generate with Replicate',
|
||||
'score' => 5,
|
||||
'tagline' => "Generate text, audio and images using Replicate's API.",
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1578,6 +1608,7 @@ return [
|
|||
'icon' => 'icon-document-search',
|
||||
'id' => 'sync-with-pinecone',
|
||||
'name' => 'Sync with Pinecone',
|
||||
'score' => 4,
|
||||
'tagline' => "Sync your Appwrite database with Pinecone's vector database.",
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1641,6 +1672,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'rag-with-langchain',
|
||||
'name' => 'RAG with LangChain',
|
||||
'score' => 6,
|
||||
'tagline' => 'Generate text using a LangChain RAG model',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1704,6 +1736,7 @@ return [
|
|||
'icon' => 'icon-chat',
|
||||
'id' => 'speak-with-elevenlabs',
|
||||
'name' => 'Speak with ElevenLabs',
|
||||
'score' => 5,
|
||||
'tagline' => 'Convert text to speech using the ElevenLabs API.',
|
||||
'permissions' => ['any'],
|
||||
'cron' => '',
|
||||
|
|
@ -1759,6 +1792,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'speak-with-lmnt',
|
||||
'name' => 'Speak with LMNT',
|
||||
'score' => 5,
|
||||
'tagline' => 'Convert text to speech using the LMNT API.',
|
||||
'permissions' => ['any'],
|
||||
'cron' => '',
|
||||
|
|
@ -1800,6 +1834,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'chat-with-anyscale',
|
||||
'name' => 'Chat with AnyScale',
|
||||
'score' => 5,
|
||||
'tagline' => 'Create a chatbot using the AnyScale API.',
|
||||
'permissions' => ['any'],
|
||||
'cron' => '',
|
||||
|
|
@ -1841,6 +1876,7 @@ return [
|
|||
'icon' => 'icon-music-note',
|
||||
'id' => 'music-generation-with-huggingface',
|
||||
'name' => 'Music generation',
|
||||
'score' => 4,
|
||||
'tagline' => 'Generate music from a text prompt using the Hugging Face inference API.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1883,6 +1919,7 @@ return [
|
|||
'icon' => 'icon-chip',
|
||||
'id' => 'generate-with-fal-ai',
|
||||
'name' => 'Generate with fal.ai',
|
||||
'score' => 5,
|
||||
'tagline' => "Generate images using fal.ai's API.",
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1918,6 +1955,7 @@ return [
|
|||
'icon' => 'icon-currency-dollar',
|
||||
'id' => 'subscriptions-with-lemon-squeezy',
|
||||
'name' => 'Subscriptions with Lemon Squeezy',
|
||||
'score' => 6,
|
||||
'tagline' => 'Receive recurring card payments and grant subscribers extra permissions.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
@ -1973,6 +2011,7 @@ return [
|
|||
'icon' => 'icon-currency-dollar',
|
||||
'id' => 'payments-with-lemon-squeezy',
|
||||
'name' => 'Payments with Lemon Squeezy',
|
||||
'score' => 6,
|
||||
'tagline' => 'Receive card payments and store paid orders.',
|
||||
'permissions' => ['any'],
|
||||
'events' => [],
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
@ -77,15 +87,6 @@ const TEMPLATE_FRAMEWORKS = [
|
|||
'adapter' => 'static',
|
||||
'fallbackFile' => '',
|
||||
],
|
||||
'OTHER' => [
|
||||
'key' => 'other',
|
||||
'name' => 'Other',
|
||||
'installCommand' => 'npm install',
|
||||
'buildCommand' => 'npm run build',
|
||||
'buildRuntime' => 'node-22',
|
||||
'adapter' => 'static',
|
||||
'fallbackFile' => 'index.html',
|
||||
],
|
||||
'VITE' => [
|
||||
'key' => 'vite',
|
||||
'name' => 'Vite',
|
||||
|
|
@ -115,6 +116,15 @@ const TEMPLATE_FRAMEWORKS = [
|
|||
'outputDirectory' => './dist/angular/browser',
|
||||
'fallbackFile' => 'index.html',
|
||||
],
|
||||
'ANALOG' => [
|
||||
'key' => 'analog',
|
||||
'name' => 'Analog',
|
||||
'installCommand' => 'npm install',
|
||||
'buildCommand' => 'npm run build',
|
||||
'buildRuntime' => 'node-22',
|
||||
'adapter' => 'ssr',
|
||||
'outputDirectory' => './dist/analog',
|
||||
],
|
||||
'VUE' => [
|
||||
'key' => 'vue',
|
||||
'name' => 'Vue.js',
|
||||
|
|
@ -134,6 +144,16 @@ const TEMPLATE_FRAMEWORKS = [
|
|||
'adapter' => 'static',
|
||||
'outputDirectory' => './',
|
||||
],
|
||||
'LYNX' => [
|
||||
'key' => 'lynx',
|
||||
'name' => 'Lynx',
|
||||
'installCommand' => 'npm install && cd web && npm install && cd ..',
|
||||
'buildCommand' => 'npm run build && cd web && npm run build && cd ..',
|
||||
'buildRuntime' => 'node-22',
|
||||
'adapter' => 'static',
|
||||
'outputDirectory' => './web/dist',
|
||||
'fallbackFile' => 'index.html',
|
||||
],
|
||||
];
|
||||
|
||||
function getFramework(string $frameworkEnum, array $overrides)
|
||||
|
|
@ -143,10 +163,119 @@ function getFramework(string $frameworkEnum, array $overrides)
|
|||
}
|
||||
|
||||
return [
|
||||
[
|
||||
'key' => 'template-for-documentation',
|
||||
'name' => 'Documentation template',
|
||||
'tagline' => 'Modern site to store your knowledge with a clean design, full-text search, dark mode, and more.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::DOCUMENTATION],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-documentation-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-documentation-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ASTRO', [
|
||||
'providerRootDirectory' => './',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'template-for-documentation',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.1.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'lynx-starter',
|
||||
'name' => 'Lynx Starter',
|
||||
'tagline' => 'Sample application built with Lynx, a cross-platform framework focused on performance.',
|
||||
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/lynx-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/lynx-starter-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('LYNX', [
|
||||
'providerRootDirectory' => './lynx/starter',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'templates-for-sites',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
[
|
||||
'key' => 'vitepress',
|
||||
'name' => 'Vitepress',
|
||||
'tagline' => 'Platform for documentation and knowledge sharing powered by Vite.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'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',
|
||||
'tagline' => 'Platform for documentation and knowledge sharing powered by Vue.',
|
||||
'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'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',
|
||||
'tagline' => 'Platform for documentation and knowledge sharing powered by React.',
|
||||
'score' => 4, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'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' => ['portfolio'],
|
||||
'tagline' => 'Personal website for creators to merge all URLs to social profiles.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/nxt-lnk-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/nxt-lnk-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -160,11 +289,12 @@ return [
|
|||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
|
||||
[
|
||||
'key' => 'magic-portfolio',
|
||||
'name' => 'Magic Portfolio',
|
||||
'useCases' => ['portfolio'],
|
||||
'tagline' => 'Complex personal website to showcase your projects, articles, and more.',
|
||||
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/magic-portfolio-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/magic-portfolio-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -178,11 +308,12 @@ return [
|
|||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
|
||||
[
|
||||
'key' => 'littlelink',
|
||||
'name' => 'LittleLink',
|
||||
'useCases' => ['portfolio'],
|
||||
'tagline' => 'Personal website for creators to merge all URLs to social profiles.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/littlelink-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/littlelink-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -196,11 +327,12 @@ return [
|
|||
'providerVersion' => '0.3.*',
|
||||
'variables' => []
|
||||
],
|
||||
|
||||
[
|
||||
'key' => 'logspot',
|
||||
'name' => 'Logspot',
|
||||
'useCases' => ['blog'],
|
||||
'tagline' => 'Website to publish changelogs of your application.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::BLOG],
|
||||
'screenshotDark' => $url . '/images/sites/templates/logspot-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/logspot-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -220,7 +352,9 @@ return [
|
|||
[
|
||||
'key' => 'astro-nano',
|
||||
'name' => 'Astro Nano',
|
||||
'useCases' => ['portfolio'],
|
||||
'tagline' => 'Minimal personal website to showcase your projects, articles, and more.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-nano-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-nano-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -239,7 +373,9 @@ return [
|
|||
[
|
||||
'key' => 'astro-starlight',
|
||||
'name' => 'Astro Starlight',
|
||||
'useCases' => ['documentation'],
|
||||
'tagline' => 'Platform for documentation and knowledge sharing powered by Astro.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::DOCUMENTATION],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-starlight-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-starlight-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -258,7 +394,9 @@ return [
|
|||
[
|
||||
'key' => 'astro-sphere',
|
||||
'name' => 'Astro Sphere',
|
||||
'useCases' => ['portfolio'],
|
||||
'tagline' => 'Modern personal website to showcase your projects, articles, and more.',
|
||||
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-sphere-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-sphere-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -277,7 +415,9 @@ return [
|
|||
[
|
||||
'key' => 'astro-starlog',
|
||||
'name' => 'Astro Starlog',
|
||||
'useCases' => ['blog'],
|
||||
'tagline' => 'Platform for publishing written content and media powered by Astro.',
|
||||
'score' => 5, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::BLOG],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-starlog-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-starlog-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -296,7 +436,9 @@ return [
|
|||
[
|
||||
'key' => 'onelink',
|
||||
'name' => 'Onelink',
|
||||
'useCases' => ['portfolio'],
|
||||
'tagline' => 'Personal website for creators to merge all URLs to social profiles.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/onelink-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/onelink-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -316,13 +458,15 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-flutter',
|
||||
'name' => 'Flutter starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Flutter application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'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',
|
||||
|
|
@ -359,7 +503,9 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-js',
|
||||
'name' => 'JavaScript starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple JavaScript application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-js-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-js-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -401,14 +547,16 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-angular',
|
||||
'name' => 'Angular starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Angular application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'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',
|
||||
|
|
@ -442,10 +590,145 @@ return [
|
|||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'key' => 'starter-for-astro',
|
||||
'name' => 'Astro starter',
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Astro application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-astro-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-astro-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ASTRO', [
|
||||
'providerRootDirectory' => './',
|
||||
'adapter' => 'static',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'starter-for-astro',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.1.*',
|
||||
'variables' => [
|
||||
[
|
||||
'name' => 'PUBLIC_APPWRITE_ENDPOINT',
|
||||
'description' => 'Endpoint of Appwrite server',
|
||||
'value' => '{apiEndpoint}',
|
||||
'placeholder' => '{apiEndpoint}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
[
|
||||
'name' => 'PUBLIC_APPWRITE_PROJECT_ID',
|
||||
'description' => 'Your Appwrite project ID',
|
||||
'value' => '{projectId}',
|
||||
'placeholder' => '{projectId}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
[
|
||||
'name' => 'PUBLIC_APPWRITE_PROJECT_NAME',
|
||||
'description' => 'Your Appwrite project name',
|
||||
'value' => '{projectName}',
|
||||
'placeholder' => '{projectName}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'key' => 'starter-for-analog',
|
||||
'name' => 'Analog starter',
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Analog application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-analog-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-analog-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('ANALOG', [
|
||||
'providerRootDirectory' => './',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'starter-for-analog',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.1.*',
|
||||
'variables' => [
|
||||
[
|
||||
'name' => 'VITE_APPWRITE_ENDPOINT',
|
||||
'description' => 'Endpoint of Appwrite server',
|
||||
'value' => '{apiEndpoint}',
|
||||
'placeholder' => '{apiEndpoint}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
[
|
||||
'name' => 'VITE_APPWRITE_PROJECT_ID',
|
||||
'description' => 'Your Appwrite project ID',
|
||||
'value' => '{projectId}',
|
||||
'placeholder' => '{projectId}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
[
|
||||
'name' => 'VITE_APPWRITE_PROJECT_NAME',
|
||||
'description' => 'Your Appwrite project name',
|
||||
'value' => '{projectName}',
|
||||
'placeholder' => '{projectName}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'key' => 'starter-for-remix',
|
||||
'name' => 'Remix starter',
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Remix application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-remix-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-remix-light.png',
|
||||
'frameworks' => [
|
||||
getFramework('REMIX', [
|
||||
'providerRootDirectory' => './',
|
||||
]),
|
||||
],
|
||||
'vcsProvider' => 'github',
|
||||
'providerRepositoryId' => 'starter-for-remix',
|
||||
'providerOwner' => 'appwrite',
|
||||
'providerVersion' => '0.1.*',
|
||||
'variables' => [
|
||||
[
|
||||
'name' => 'VITE_APPWRITE_ENDPOINT',
|
||||
'description' => 'Endpoint of Appwrite server',
|
||||
'value' => '{apiEndpoint}',
|
||||
'placeholder' => '{apiEndpoint}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
[
|
||||
'name' => 'VITE_APPWRITE_PROJECT_ID',
|
||||
'description' => 'Your Appwrite project ID',
|
||||
'value' => '{projectId}',
|
||||
'placeholder' => '{projectId}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
[
|
||||
'name' => 'VITE_APPWRITE_PROJECT_NAME',
|
||||
'description' => 'Your Appwrite project name',
|
||||
'value' => '{projectName}',
|
||||
'placeholder' => '{projectName}',
|
||||
'required' => true,
|
||||
'type' => 'text'
|
||||
],
|
||||
]
|
||||
],
|
||||
[
|
||||
'key' => 'starter-for-svelte',
|
||||
'name' => 'Svelte starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Svelte application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-svelte-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-svelte-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -487,7 +770,9 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-react',
|
||||
'name' => 'React starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple React application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-react-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -529,7 +814,9 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-vue',
|
||||
'name' => 'Vue starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Vue application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-vue-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-vue-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -571,7 +858,9 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-react-native',
|
||||
'name' => 'React Native starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple React Native application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-native-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-react-native-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -614,7 +903,9 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-nextjs',
|
||||
'name' => 'Next.js starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Next.js application integrated with Appwrite SDK.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-nextjs-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-nextjs-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -656,7 +947,9 @@ return [
|
|||
[
|
||||
'key' => 'starter-for-nuxt',
|
||||
'name' => 'Nuxt starter',
|
||||
'useCases' => ['starter'],
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'tagline' => 'Simple Nuxt application integrated with Appwrite SDK.',
|
||||
'score' => 3, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'screenshotDark' => $url . '/images/sites/templates/starter-for-nuxt-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/starter-for-nuxt-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -698,7 +991,9 @@ return [
|
|||
[
|
||||
'key' => 'template-for-event',
|
||||
'name' => 'Event template',
|
||||
'useCases' => ['events'],
|
||||
'tagline' => 'Hackathon landing page with support for project submissions.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::EVENTS],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-event-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-event-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -734,7 +1029,9 @@ return [
|
|||
[
|
||||
'key' => 'template-for-portfolio',
|
||||
'name' => 'Portfolio template',
|
||||
'useCases' => ['portfolio'],
|
||||
'tagline' => 'Simple personal website to showcase your projects, articles, and more.',
|
||||
'score' => 6, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::PORTFOLIO],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-portfolio-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-portfolio-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -751,7 +1048,9 @@ return [
|
|||
[
|
||||
'key' => 'template-for-store',
|
||||
'name' => 'Store template',
|
||||
'useCases' => ['ecommerce'],
|
||||
'tagline' => 'E-commerce platform for selling products with Stripe integration.',
|
||||
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::ECOMMERCE],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-store-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-store-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -793,7 +1092,9 @@ return [
|
|||
[
|
||||
'key' => 'template-for-blog',
|
||||
'name' => 'Blog template',
|
||||
'useCases' => ['blog'],
|
||||
'tagline' => 'Platform for publishing written content and media.',
|
||||
'score' => 7, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::BLOG],
|
||||
'screenshotDark' => $url . '/images/sites/templates/template-for-blog-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/template-for-blog-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -807,10 +1108,13 @@ return [
|
|||
'providerVersion' => '0.1.*',
|
||||
'variables' => []
|
||||
],
|
||||
// TODO: Remove astro starter eventually, or add all frameworks's starters
|
||||
[
|
||||
'key' => 'astro-starter',
|
||||
'name' => 'Astro starter',
|
||||
'useCases' => ['starter'],
|
||||
'tagline' => 'Sample application built with Astro, a content-driven web framework.',
|
||||
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/astro-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/astro-starter-light.png',
|
||||
'frameworks' => [
|
||||
|
|
@ -827,7 +1131,9 @@ return [
|
|||
[
|
||||
'key' => 'remix-starter',
|
||||
'name' => 'Remix starter',
|
||||
'useCases' => ['starter'],
|
||||
'tagline' => 'Sample application built with Remix, a React meta-framework.',
|
||||
'score' => 1, // 0 to 10 based on looks of screenshot (avoid 1,2,3,8,9,10 if possible)
|
||||
'useCases' => [UseCases::STARTER],
|
||||
'screenshotDark' => $url . '/images/sites/templates/remix-starter-dark.png',
|
||||
'screenshotLight' => $url . '/images/sites/templates/remix-starter-light.png',
|
||||
'frameworks' => [
|
||||
|
|
|
|||
|
|
@ -90,13 +90,40 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET',
|
||||
'description' => 'A DNS A record hostname to serve as a CNAME target for your Appwrite custom domains. You can use the same value as used for the Appwrite \'_APP_DOMAIN\' variable. The default value is \'localhost\'.',
|
||||
'description' => 'Deprecated since 1.7.0. A DNS A record hostname to serve as a CNAME target for your Appwrite custom domains. You can use the same value as used for the Appwrite \'_APP_DOMAIN\' variable. The default value is \'localhost\'.',
|
||||
'introduction' => '',
|
||||
'default' => 'localhost',
|
||||
'required' => true,
|
||||
'question' => 'Enter a DNS A record hostname to serve as a CNAME for your custom domains.' . PHP_EOL . 'You can use the same value as used for the Appwrite hostname.',
|
||||
'filter' => 'domainTarget'
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_CNAME',
|
||||
'description' => 'A domain that can be used as DNS CNAME record to point to instance of Appwrite server.',
|
||||
'introduction' => '',
|
||||
'default' => 'localhost',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_AAAA',
|
||||
'description' => 'An IPv6 that can be used as DNS AAAA record to point to instance of Appwrite server.',
|
||||
'introduction' => '',
|
||||
'default' => '::1',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DOMAIN_TARGET_A',
|
||||
'description' => 'An IPV4 that can be used as DNS A record to point to instance of Appwrite server.',
|
||||
'introduction' => '',
|
||||
'default' => '127.0.0.1',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_CONSOLE_WHITELIST_ROOT',
|
||||
'description' => 'This option allows you to disable the creation of new users on the Appwrite console. When enabled only 1 user will be able to use the registration form. New users can be added by inviting them to your project. By default this option is enabled.',
|
||||
|
|
@ -1048,13 +1075,22 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_MAINTENANCE_RETENTION_AUDIT',
|
||||
'description' => 'IThe maximum duration (in seconds) upto which to retain audit logs. The default value is 1209600 seconds (14 days).',
|
||||
'description' => 'The maximum duration (in seconds) upto which to retain audit logs. The default value is 1209600 seconds (14 days).',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => '1209600',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE',
|
||||
'description' => 'The maximum duration (in seconds) upto which to retain console audit logs. The default value is 15778800 seconds (6 months).',
|
||||
'introduction' => '1.6.2',
|
||||
'default' => '15778800',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_MAINTENANCE_RETENTION_ABUSE',
|
||||
'description' => 'The maximum duration (in seconds) upto which to retain abuse logs. The default value is 86400 seconds (1 day).',
|
||||
|
|
|
|||
|
|
@ -496,6 +496,7 @@ App::get('/v1/avatars/qr')
|
|||
'addQuietzone' => true,
|
||||
'quietzoneSize' => $margin,
|
||||
'outputType' => QRCode::OUTPUT_IMAGICK,
|
||||
'scale' => 15,
|
||||
]);
|
||||
|
||||
$qrcode = new QRCode($options);
|
||||
|
|
@ -510,7 +511,7 @@ App::get('/v1/avatars/qr')
|
|||
$response
|
||||
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
|
||||
->setContentType('image/png')
|
||||
->send($image->output('png', 9));
|
||||
->send($image->output('png', 90));
|
||||
});
|
||||
|
||||
App::get('/v1/avatars/initials')
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ use Appwrite\SDK\Response as SDKResponse;
|
|||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
App::init()
|
||||
|
|
@ -40,10 +42,21 @@ App::get('/v1/console/variables')
|
|||
))
|
||||
->inject('response')
|
||||
->action(function (Response $response) {
|
||||
$isDomainEnabled = !empty(System::getEnv('_APP_DOMAIN', ''))
|
||||
&& !empty(System::getEnv('_APP_DOMAIN_TARGET', ''))
|
||||
&& System::getEnv('_APP_DOMAIN', '') !== 'localhost'
|
||||
&& System::getEnv('_APP_DOMAIN_TARGET', '') !== 'localhost';
|
||||
$validator = new Domain(System::getEnv('_APP_DOMAIN'));
|
||||
$isDomainValid = !empty(System::getEnv('_APP_DOMAIN', '')) && $validator->isKnown() && !$validator->isTest();
|
||||
|
||||
$validator = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
|
||||
$isCNAMEValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_CNAME', '')) && $validator->isKnown() && !$validator->isTest();
|
||||
|
||||
$validator = new IP(IP::V4);
|
||||
$isAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_A', '')) && ($validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_A')));
|
||||
|
||||
$validator = new IP(IP::V6);
|
||||
$isAAAAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_AAAA', '')) && $validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA'));
|
||||
|
||||
$isDomainEnabled = $isDomainValid && (
|
||||
$isAAAAValid || $isAValid || $isCNAMEValid
|
||||
);
|
||||
|
||||
$isVcsEnabled = !empty(System::getEnv('_APP_VCS_GITHUB_APP_NAME', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', ''))
|
||||
|
|
@ -54,7 +67,9 @@ App::get('/v1/console/variables')
|
|||
$isAssistantEnabled = !empty(System::getEnv('_APP_ASSISTANT_OPENAI_API_KEY', ''));
|
||||
|
||||
$variables = new Document([
|
||||
'_APP_DOMAIN_TARGET' => System::getEnv('_APP_DOMAIN_TARGET'),
|
||||
'_APP_DOMAIN_TARGET_CNAME' => System::getEnv('_APP_DOMAIN_TARGET_CNAME'),
|
||||
'_APP_DOMAIN_TARGET_AAAA' => System::getEnv('_APP_DOMAIN_TARGET_AAAA'),
|
||||
'_APP_DOMAIN_TARGET_A' => System::getEnv('_APP_DOMAIN_TARGET_A'),
|
||||
'_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'),
|
||||
'_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'),
|
||||
'_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'),
|
||||
|
|
@ -62,6 +77,7 @@ App::get('/v1/console/variables')
|
|||
'_APP_DOMAIN_ENABLED' => $isDomainEnabled,
|
||||
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled,
|
||||
'_APP_DOMAIN_SITES' => System::getEnv('_APP_DOMAIN_SITES'),
|
||||
'_APP_DOMAIN_FUNCTIONS' => System::getEnv('_APP_DOMAIN_FUNCTIONS'),
|
||||
'_APP_OPTIONS_FORCE_HTTPS' => System::getEnv('_APP_OPTIONS_FORCE_HTTPS'),
|
||||
'_APP_DOMAINS_NAMESERVERS' => System::getEnv('_APP_DOMAINS_NAMESERVERS'),
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Appwrite\Event\Certificate;
|
|||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
|
|
@ -21,6 +21,8 @@ use Utopia\Database\Validator\UID;
|
|||
use Utopia\Domains\Domain;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
App::get('/v1/proxy/rules')
|
||||
|
|
@ -208,17 +210,27 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
|||
throw new Exception(Exception::RULE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Domain target must be configured as environment variable.');
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
if ($rule->getAttribute('verification') === true) {
|
||||
return $response->dynamic($rule, Response::MODEL_PROXY_RULE);
|
||||
}
|
||||
|
||||
$validator = new CNAME($target->get()); // Verify Domain with DNS records
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
$domain = new Domain($rule->getAttribute('domain', ''));
|
||||
|
||||
$validationStart = \microtime(true);
|
||||
|
|
@ -226,7 +238,14 @@ App::patch('/v1/proxy/rules/:ruleId/verification')
|
|||
$log->addExtra('dnsTiming', \strval(\microtime(true) - $validationStart));
|
||||
$log->addTag('dnsDomain', $domain->get());
|
||||
|
||||
$error = $validator->getLogs();
|
||||
$errors = [];
|
||||
foreach ($validators as $validator) {
|
||||
if (!empty($validator->getLogs())) {
|
||||
$errors[] = $validator->getLogs();
|
||||
}
|
||||
}
|
||||
|
||||
$error = \implode("\n", $errors);
|
||||
$log->addExtra('dnsResponse', \is_array($error) ? \json_encode($error) : \strval($error));
|
||||
|
||||
throw new Exception(Exception::RULE_VERIFICATION_FAILED);
|
||||
|
|
|
|||
|
|
@ -615,7 +615,10 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership)) :
|
||||
$dbForProject->createDocument('memberships', $membership);
|
||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
|
||||
if ($isPrivilegedUser || $isAppUser) {
|
||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
}
|
||||
|
||||
} elseif ($membership->getAttribute('confirm') === false) {
|
||||
$membership->setAttribute('secret', Auth::hash($secret));
|
||||
|
|
@ -1031,7 +1034,6 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->param('membershipId', '', new UID(), 'Membership ID.')
|
||||
->param('roles', [], function (Document $project) {
|
||||
if ($project->getId() === 'console') {
|
||||
;
|
||||
$roles = array_keys(Config::getParam('roles', []));
|
||||
array_filter($roles, function ($role) {
|
||||
return !in_array($role, [Auth::USER_ROLE_APPS, Auth::USER_ROLE_GUESTS, Auth::USER_ROLE_USERS]);
|
||||
|
|
@ -1043,9 +1045,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
if ($team->isEmpty()) {
|
||||
|
|
@ -1066,6 +1069,21 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
$isAppUser = Auth::isAppUser(Authorization::getRoles());
|
||||
$isOwner = Authorization::isRole('team:' . $team->getId() . '/owner');
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
// Quick check: fetch up to 2 owners to determine if only one exists
|
||||
$ownersCount = $dbForProject->count(
|
||||
collection: 'memberships',
|
||||
queries: [Query::contains('roles', ['owner'])],
|
||||
max: 2
|
||||
);
|
||||
|
||||
// Prevent role change if there's only one owner left,
|
||||
// the requester is that owner, and the new `$roles` no longer include 'owner'!
|
||||
if ($ownersCount === 1 && $isOwner && !\in_array('owner', $roles)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'There must be at least one owner in the organization.');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to modify roles');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use Appwrite\SDK\Method;
|
|||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Identities;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Memberships;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Targets;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Users;
|
||||
use Appwrite\Utopia\Request;
|
||||
|
|
@ -799,9 +800,11 @@ App::get('/v1/users/:userId/memberships')
|
|||
]
|
||||
))
|
||||
->param('userId', '', new UID(), 'User ID.')
|
||||
->param('queries', [], new Memberships(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Memberships::ALLOWED_ATTRIBUTES), true)
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $userId, Response $response, Database $dbForProject) {
|
||||
->action(function (string $userId, array $queries, string $search, Response $response, Database $dbForProject) {
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
||||
|
|
@ -809,6 +812,19 @@ App::get('/v1/users/:userId/memberships')
|
|||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
if (!empty($search)) {
|
||||
$queries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
// Set internal queries
|
||||
$queries[] = Query::equal('userInternalId', [$user->getInternalId()]);
|
||||
|
||||
$memberships = array_map(function ($membership) use ($dbForProject, $user) {
|
||||
$team = $dbForProject->getDocument('teams', $membership->getAttribute('teamId'));
|
||||
|
||||
|
|
@ -818,7 +834,7 @@ App::get('/v1/users/:userId/memberships')
|
|||
->setAttribute('userEmail', $user->getAttribute('email'));
|
||||
|
||||
return $membership;
|
||||
}, $user->getAttribute('memberships', []));
|
||||
}, $dbForProject->find('memberships', $queries));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'memberships' => $memberships,
|
||||
|
|
|
|||
|
|
@ -134,12 +134,12 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
|||
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
|
||||
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '', '');
|
||||
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '');
|
||||
|
||||
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
|
||||
} else {
|
||||
$comment = new Comment();
|
||||
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '', '');
|
||||
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '');
|
||||
$latestCommentId = \strval($github->createComment($owner, $repositoryName, $providerPullRequestId, $comment->generateComment()));
|
||||
|
||||
if (!empty($latestCommentId)) {
|
||||
|
|
@ -176,7 +176,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
|||
$latestCommentId = $comment->getAttribute('providerCommentId', '');
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
|
||||
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '', '');
|
||||
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '');
|
||||
|
||||
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
|
||||
}
|
||||
|
|
@ -219,7 +219,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
|||
$commands[] = $resource->getAttribute('commands', '');
|
||||
}
|
||||
|
||||
$deployment = $dbForProject->createDocument('deployments', new Document([
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->createDocument('deployments', new Document([
|
||||
'$id' => $deploymentId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
|
|
@ -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,
|
||||
|
|
@ -251,14 +253,14 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
|||
'providerBranch' => $providerBranch,
|
||||
'search' => implode(' ', [$deploymentId, $resource->getAttribute('entrypoint', '')]),
|
||||
'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);
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource));
|
||||
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
$projectId = $project->getId();
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ Config::setParam('domainVerification', false);
|
|||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey)
|
||||
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey)
|
||||
{
|
||||
$utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml');
|
||||
|
||||
|
|
@ -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,12 +415,11 @@ 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 */
|
||||
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
|
||||
try {
|
||||
$version = match ($type) {
|
||||
'function' => $resource->getAttribute('version', 'v2'),
|
||||
|
|
@ -438,7 +442,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,24 +477,28 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
|||
);
|
||||
|
||||
// Branded 404 override
|
||||
if ($executionResponse['statusCode'] === 404 && $resource->getAttribute('adapter', '') === 'static') {
|
||||
$isResponseBranded = false;
|
||||
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']);
|
||||
$isResponseBranded = true;
|
||||
}
|
||||
|
||||
// Branded banner for previews
|
||||
if (\is_null($apiKey) || $apiKey->isBannerDisabled() === false) {
|
||||
$transformation = new Transformation();
|
||||
$transformation->addAdapter(new Preview());
|
||||
$transformation->setInput($executionResponse['body']);
|
||||
$transformation->setTraits($executionResponse['headers']);
|
||||
if ($isPreview && $transformation->transform()) {
|
||||
$executionResponse['body'] = $transformation->getOutput();
|
||||
if (!$isResponseBranded) {
|
||||
if (\is_null($apiKey) || $apiKey->isBannerDisabled() === false) {
|
||||
$transformation = new Transformation();
|
||||
$transformation->addAdapter(new Preview());
|
||||
$transformation->setInput($executionResponse['body']);
|
||||
$transformation->setTraits($executionResponse['headers']);
|
||||
if ($isPreview && $transformation->transform()) {
|
||||
$executionResponse['body'] = $transformation->getOutput();
|
||||
|
||||
foreach ($executionResponse['headers'] as $key => $value) {
|
||||
if (\strtolower($key) === 'content-length') {
|
||||
$executionResponse['headers'][$key] = \strlen($executionResponse['body']);
|
||||
foreach ($executionResponse['headers'] as $key => $value) {
|
||||
if (\strtolower($key) === 'content-length') {
|
||||
$executionResponse['headers'][$key] = \strlen($executionResponse['body']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -653,10 +661,11 @@ App::init()
|
|||
->inject('queueForEvents')
|
||||
->inject('queueForCertificates')
|
||||
->inject('queueForFunctions')
|
||||
->inject('executor')
|
||||
->inject('isResourceBlocked')
|
||||
->inject('previewHostname')
|
||||
->inject('apiKey')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, Executor $executor, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
/*
|
||||
* Appwrite Router
|
||||
*/
|
||||
|
|
@ -664,7 +673,7 @@ App::init()
|
|||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if ($host !== $mainDomain || !empty($previewHostname)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
|
|
@ -917,12 +926,13 @@ App::options()
|
|||
->inject('queueForEvents')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('queueForFunctions')
|
||||
->inject('executor')
|
||||
->inject('geodb')
|
||||
->inject('isResourceBlocked')
|
||||
->inject('previewHostname')
|
||||
->inject('project')
|
||||
->inject('apiKey')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, ?Key $apiKey) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, ?Key $apiKey) {
|
||||
/*
|
||||
* Appwrite Router
|
||||
*/
|
||||
|
|
@ -930,7 +940,7 @@ App::options()
|
|||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if ($host !== $mainDomain || !empty($previewHostname)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1047,17 +1057,18 @@ App::error()
|
|||
if (!empty($providerConfig) && $error->getCode() >= 400 && $error->getCode() < 500) {
|
||||
// Register error logger
|
||||
try {
|
||||
$loggingProvider = new DSN($providerConfig ?? '');
|
||||
$loggingProvider = new DSN($providerConfig);
|
||||
$providerName = $loggingProvider->getScheme();
|
||||
|
||||
if (!empty($providerName) && $providerName === 'sentry') {
|
||||
$key = $loggingProvider->getPassword();
|
||||
$projectId = $loggingProvider->getUser() ?? '';
|
||||
$host = 'https://' . $loggingProvider->getHost();
|
||||
$sampleRate = $loggingProvider->getParam('sample', 0.01);
|
||||
|
||||
$adapter = new Sentry($projectId, $key, $host);
|
||||
$logger = new Logger($adapter);
|
||||
$logger->setSample(0.01);
|
||||
$logger->setSample($sampleRate);
|
||||
$publish = true;
|
||||
} else {
|
||||
throw new \Exception('Invalid experimental logging provider');
|
||||
|
|
@ -1238,11 +1249,12 @@ App::get('/robots.txt')
|
|||
->inject('queueForEvents')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('queueForFunctions')
|
||||
->inject('executor')
|
||||
->inject('geodb')
|
||||
->inject('isResourceBlocked')
|
||||
->inject('previewHostname')
|
||||
->inject('apiKey')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
$host = $request->getHostname() ?? '';
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
|
||||
|
|
@ -1250,7 +1262,7 @@ App::get('/robots.txt')
|
|||
$template = new View(__DIR__ . '/../views/general/robots.phtml');
|
||||
$response->text($template->render(false));
|
||||
} else {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1269,11 +1281,12 @@ App::get('/humans.txt')
|
|||
->inject('queueForEvents')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('queueForFunctions')
|
||||
->inject('executor')
|
||||
->inject('geodb')
|
||||
->inject('isResourceBlocked')
|
||||
->inject('previewHostname')
|
||||
->inject('apiKey')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
$host = $request->getHostname() ?? '';
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
|
||||
|
|
@ -1281,7 +1294,7 @@ App::get('/humans.txt')
|
|||
$template = new View(__DIR__ . '/../views/general/humans.phtml');
|
||||
$response->text($template->render(false));
|
||||
} else {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,7 +399,8 @@ App::init()
|
|||
->inject('timelimit')
|
||||
->inject('mode')
|
||||
->inject('apiKey')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, string $mode, ?Key $apiKey) use ($usageDatabaseListener, $eventDatabaseListener) {
|
||||
->inject('plan')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, string $mode, ?Key $apiKey, array $plan) use ($usageDatabaseListener, $eventDatabaseListener) {
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
|
|
@ -529,6 +530,10 @@ App::init()
|
|||
|
||||
$useCache = $route->getLabel('cache', false);
|
||||
if ($useCache) {
|
||||
$route = $utopia->match($request);
|
||||
$isImageTransformation = $route->getPath() === '/v1/storage/buckets/:bucketId/files/:fileId/preview';
|
||||
$isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && !Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
$key = md5($request->getURI() . '*' . implode('*', $request->getParams()) . '*' . APP_CACHE_BUSTER);
|
||||
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$cache = new Cache(
|
||||
|
|
@ -541,7 +546,7 @@ App::init()
|
|||
$parts = explode('/', $cacheLog->getAttribute('resourceType'));
|
||||
$type = $parts[0] ?? null;
|
||||
|
||||
if ($type === 'bucket') {
|
||||
if ($type === 'bucket' && (!$isImageTransformation || !$isDisabled)) {
|
||||
$bucketId = $parts[1] ?? null;
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
|
|
@ -582,8 +587,10 @@ App::init()
|
|||
$response
|
||||
->addHeader('Cache-Control', sprintf('private, max-age=%d', $timestamp))
|
||||
->addHeader('X-Appwrite-Cache', 'hit')
|
||||
->setContentType($cacheLog->getAttribute('mimeType'))
|
||||
->send($data);
|
||||
->setContentType($cacheLog->getAttribute('mimeType'));
|
||||
if (!$isImageTransformation || !$isDisabled) {
|
||||
$response->send($data);
|
||||
}
|
||||
} else {
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use Appwrite\Extend\Exception;
|
|||
use Appwrite\GraphQL\Schema;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Executor\Executor;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
|
|
@ -38,6 +39,7 @@ use Utopia\Logger\Log;
|
|||
use Utopia\Pools\Group;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Storage\Device\AWS;
|
||||
use Utopia\Storage\Device\Backblaze;
|
||||
use Utopia\Storage\Device\DOSpaces;
|
||||
use Utopia\Storage\Device\Linode;
|
||||
|
|
@ -544,7 +546,12 @@ function getDevice(string $root, string $connection = ''): Device
|
|||
|
||||
switch ($device) {
|
||||
case Storage::DEVICE_S3:
|
||||
return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl, $url);
|
||||
if (!empty($url)) {
|
||||
return new S3($root, $accessKey, $accessSecret, $url, $region, $acl);
|
||||
} else {
|
||||
return new AWS($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
}
|
||||
// no break
|
||||
case STORAGE::DEVICE_DO_SPACES:
|
||||
$device = new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
$device->setHttpVersion(S3::HTTP_VERSION_1_1);
|
||||
|
|
@ -571,7 +578,12 @@ function getDevice(string $root, string $connection = ''): Device
|
|||
$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);
|
||||
if (!empty($s3EndpointUrl)) {
|
||||
return new S3($root, $s3AccessKey, $s3SecretKey, $s3EndpointUrl, $s3Region, $s3Acl);
|
||||
} else {
|
||||
return new AWS($root, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl);
|
||||
}
|
||||
// no break
|
||||
case Storage::DEVICE_DO_SPACES:
|
||||
$doSpacesAccessKey = System::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', '');
|
||||
$doSpacesSecretKey = System::getEnv('_APP_STORAGE_DO_SPACES_SECRET', '');
|
||||
|
|
@ -834,3 +846,5 @@ App::setResource('apiKey', function (Request $request, Document $project): ?Key
|
|||
|
||||
return Key::decode($project, $key);
|
||||
}, ['request', 'project']);
|
||||
|
||||
App::setResource('executor', fn () => new Executor(fn (string $projectId, string $deploymentId) => System::getEnv('_APP_EXECUTOR_HOST')));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -134,7 +134,8 @@ $image = $this->getParam('image', '');
|
|||
- _APP_STORAGE_WASABI_REGION
|
||||
- _APP_STORAGE_WASABI_BUCKET
|
||||
- _APP_COMPUTE_SIZE_LIMIT
|
||||
- _APP_COMPUTE_TIMEOUT
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_SITES_TIMEOUT
|
||||
- _APP_COMPUTE_BUILD_TIMEOUT
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
|
|
@ -149,6 +150,7 @@ $image = $this->getParam('image', '');
|
|||
- _APP_MAINTENANCE_RETENTION_CACHE
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
|
||||
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
- _APP_SMS_PROVIDER
|
||||
|
|
@ -341,6 +343,7 @@ $image = $this->getParam('image', '');
|
|||
- _APP_EXECUTOR_HOST
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
|
||||
- _APP_MAINTENANCE_RETENTION_EXECUTION
|
||||
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
|
|
@ -404,7 +407,8 @@ $image = $this->getParam('image', '');
|
|||
- _APP_VCS_GITHUB_APP_NAME
|
||||
- _APP_VCS_GITHUB_PRIVATE_KEY
|
||||
- _APP_VCS_GITHUB_APP_ID
|
||||
- _APP_COMPUTE_TIMEOUT
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_SITES_TIMEOUT
|
||||
- _APP_COMPUTE_BUILD_TIMEOUT
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
|
|
@ -495,7 +499,8 @@ $image = $this->getParam('image', '');
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_COMPUTE_TIMEOUT
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_SITES_TIMEOUT
|
||||
- _APP_COMPUTE_BUILD_TIMEOUT
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
|
|
@ -652,6 +657,7 @@ $image = $this->getParam('image', '');
|
|||
- _APP_MAINTENANCE_RETENTION_CACHE
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
|
||||
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,9 @@ use Appwrite\Event\Migration;
|
|||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\StatsUsageDump;
|
||||
/** remove */
|
||||
/** /remove */
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Platform\Appwrite;
|
||||
use Executor\Executor;
|
||||
use Swoole\Runtime;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
|
|
@ -215,15 +214,18 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
|||
}, ['pools', 'cache']);
|
||||
|
||||
Server::setResource('abuseRetention', function () {
|
||||
return time() - (int) System::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', 86400);
|
||||
return time() - (int) System::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', 86400); // 1 day
|
||||
});
|
||||
|
||||
Server::setResource('auditRetention', function () {
|
||||
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 1209600));
|
||||
});
|
||||
Server::setResource('auditRetention', function (Document $project) {
|
||||
if ($project->getId() === 'console') {
|
||||
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE', 15778800)); // 6 months
|
||||
}
|
||||
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', 1209600)); // 14 days
|
||||
}, ['project']);
|
||||
|
||||
Server::setResource('executionRetention', function () {
|
||||
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_EXECUTION', 1209600));
|
||||
return DateTime::addSeconds(new \DateTime(), -1 * System::getEnv('_APP_MAINTENANCE_RETENTION_EXECUTION', 1209600)); // 14 days
|
||||
});
|
||||
|
||||
Server::setResource('cache', function (Registry $register) {
|
||||
|
|
@ -416,6 +418,8 @@ Server::setResource('logError', function (Registry $register, Document $project)
|
|||
};
|
||||
}, ['register', 'project']);
|
||||
|
||||
Server::setResource('executor', fn () => new Executor(fn (string $projectId, string $deploymentId) => System::getEnv('_APP_EXECUTOR_HOST')));
|
||||
|
||||
$pools = $register->get('pools');
|
||||
$platform = new Appwrite();
|
||||
$args = $platform->getEnv('argv');
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
"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.52.*",
|
||||
"utopia-php/analytics": "0.10.*",
|
||||
|
|
@ -53,11 +53,11 @@
|
|||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/detector": "0.1.*",
|
||||
"utopia-php/database": "0.61.*",
|
||||
"utopia-php/database": "0.64.*",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/fetch": "0.3.*",
|
||||
"utopia-php/fetch": "0.4.*",
|
||||
"utopia-php/image": "0.8.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
"utopia-php/migration": "0.8.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.7.*",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.9.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
"utopia-php/system": "0.9.*",
|
||||
"utopia-php/telemetry": "0.1.*",
|
||||
"utopia-php/vcs": "0.10.*",
|
||||
"utopia-php/websocket": "0.1.*",
|
||||
"utopia-php/websocket": "0.3.*",
|
||||
"matomo/device-detector": "6.1.*",
|
||||
"dragonmantank/cron-expression": "3.3.2",
|
||||
"phpmailer/phpmailer": "6.9.1",
|
||||
|
|
|
|||
510
composer.lock
generated
|
|
@ -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": "eeb306ee6d2576e466ceea5e927664d0",
|
||||
"content-hash": "cac7679b9486588135dad678d9488f9e",
|
||||
"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.1",
|
||||
"version": "v4.30.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "f29ba8a30dfd940efb3a8a75dc44446539101f24"
|
||||
"reference": "a4c4d8565b40b9f76debc9dfeb221412eacb8ced"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/f29ba8a30dfd940efb3a8a75dc44446539101f24",
|
||||
"reference": "f29ba8a30dfd940efb3a8a75dc44446539101f24",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/a4c4d8565b40b9f76debc9dfeb221412eacb8ced",
|
||||
"reference": "a4c4d8565b40b9f76debc9dfeb221412eacb8ced",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -747,69 +747,9 @@
|
|||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.30.1"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.30.2"
|
||||
},
|
||||
"time": "2025-03-13T21:08:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Jean85/pretty-package-versions.git",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.1.0",
|
||||
"php": "^7.4|^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"jean85/composer-provided-replaced-stub-package": "^1.0",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.6",
|
||||
"rector/rector": "^2.0",
|
||||
"vimeo/psalm": "^4.3 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jean85\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Alessandro Lai",
|
||||
"email": "alessandro.lai85@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library to get pretty versions strings of installed dependencies",
|
||||
"keywords": [
|
||||
"composer",
|
||||
"package",
|
||||
"release",
|
||||
"versions"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Jean85/pretty-package-versions/issues",
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1"
|
||||
},
|
||||
"time": "2025-03-19T14:43:43+00:00"
|
||||
"time": "2025-03-26T18:01:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
|
|
@ -969,75 +909,6 @@
|
|||
},
|
||||
"time": "2023-10-02T10:01:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mongodb/mongodb",
|
||||
"version": "1.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mongodb/mongo-php-library.git",
|
||||
"reference": "b0bbd657f84219212487d01a8ffe93a789e1e488"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/b0bbd657f84219212487d01a8ffe93a789e1e488",
|
||||
"reference": "b0bbd657f84219212487d01a8ffe93a789e1e488",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-hash": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mongodb": "^1.11.0",
|
||||
"jean85/pretty-package-versions": "^1.2 || ^2.0.1",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"symfony/polyfill-php80": "^1.19"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.6",
|
||||
"symfony/phpunit-bridge": "^5.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.10.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"MongoDB\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Andreas Braun",
|
||||
"email": "andreas.braun@mongodb.com"
|
||||
},
|
||||
{
|
||||
"name": "Jeremy Mikola",
|
||||
"email": "jmikola@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "MongoDB driver library",
|
||||
"homepage": "https://jira.mongodb.org/browse/PHPLIB",
|
||||
"keywords": [
|
||||
"database",
|
||||
"driver",
|
||||
"mongodb",
|
||||
"persistence"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/mongodb/mongo-php-library/issues",
|
||||
"source": "https://github.com/mongodb/mongo-php-library/tree/1.10.0"
|
||||
},
|
||||
"time": "2021-10-20T22:22:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mustangostang/spyc",
|
||||
"version": "0.6.3",
|
||||
|
|
@ -1494,16 +1365,16 @@
|
|||
},
|
||||
{
|
||||
"name": "open-telemetry/sdk",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opentelemetry-php/sdk.git",
|
||||
"reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0"
|
||||
"reference": "0e7804c176c4b09d95b7985400aa38ce544cb7fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/37eec0fe47ddd627911f318f29b6cd48196be0c0",
|
||||
"reference": "37eec0fe47ddd627911f318f29b6cd48196be0c0",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/0e7804c176c4b09d95b7985400aa38ce544cb7fc",
|
||||
"reference": "0e7804c176c4b09d95b7985400aa38ce544cb7fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -1580,7 +1451,7 @@
|
|||
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
|
||||
"source": "https://github.com/open-telemetry/opentelemetry-php"
|
||||
},
|
||||
"time": "2025-01-29T21:40:28+00:00"
|
||||
"time": "2025-04-08T09:55:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "open-telemetry/sem-conv",
|
||||
|
|
@ -2372,16 +2243,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": {
|
||||
|
|
@ -2442,9 +2313,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",
|
||||
|
|
@ -2933,86 +2804,6 @@
|
|||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php80\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ion Bazan",
|
||||
"email": "ion.bazan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php82",
|
||||
"version": "v1.31.0",
|
||||
|
|
@ -3174,16 +2965,16 @@
|
|||
},
|
||||
{
|
||||
"name": "tbachert/spi",
|
||||
"version": "v1.0.2",
|
||||
"version": "v1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Nevay/spi.git",
|
||||
"reference": "2ddfaf815dafb45791a61b08170de8d583c16062"
|
||||
"reference": "506a79c98e1a51522e76ee921ccb6c62d52faf3a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Nevay/spi/zipball/2ddfaf815dafb45791a61b08170de8d583c16062",
|
||||
"reference": "2ddfaf815dafb45791a61b08170de8d583c16062",
|
||||
"url": "https://api.github.com/repos/Nevay/spi/zipball/506a79c98e1a51522e76ee921ccb6c62d52faf3a",
|
||||
"reference": "506a79c98e1a51522e76ee921ccb6c62d52faf3a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3220,9 +3011,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Nevay/spi/issues",
|
||||
"source": "https://github.com/Nevay/spi/tree/v1.0.2"
|
||||
"source": "https://github.com/Nevay/spi/tree/v1.0.3"
|
||||
},
|
||||
"time": "2024-10-04T16:36:12+00:00"
|
||||
"time": "2025-04-02T19:38:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thecodingmachine/safe",
|
||||
|
|
@ -3706,16 +3497,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.61.2",
|
||||
"version": "0.64.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "349fbdf4bc088f7775c7dfb8b80239a617a88436"
|
||||
"reference": "dc9c4a68c93e8bea2dfaa76d1ba308be539998bd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/349fbdf4bc088f7775c7dfb8b80239a617a88436",
|
||||
"reference": "349fbdf4bc088f7775c7dfb8b80239a617a88436",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/dc9c4a68c93e8bea2dfaa76d1ba308be539998bd",
|
||||
"reference": "dc9c4a68c93e8bea2dfaa76d1ba308be539998bd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3724,7 +3515,7 @@
|
|||
"php": ">=8.1",
|
||||
"utopia-php/cache": "0.12.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/mongo": "0.3.*"
|
||||
"utopia-php/pools": "0.8.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "1.23.*",
|
||||
|
|
@ -3756,22 +3547,22 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.61.2"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.64.2"
|
||||
},
|
||||
"time": "2025-03-15T11:47:42+00:00"
|
||||
"time": "2025-04-09T07:53:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/detector.git",
|
||||
"reference": "8617ea205738743ef3363ad95791139e82ae44d5"
|
||||
"reference": "895a4147463965b5f9cbc083b764b6476f547879"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/detector/zipball/8617ea205738743ef3363ad95791139e82ae44d5",
|
||||
"reference": "8617ea205738743ef3363ad95791139e82ae44d5",
|
||||
"url": "https://api.github.com/repos/utopia-php/detector/zipball/895a4147463965b5f9cbc083b764b6476f547879",
|
||||
"reference": "895a4147463965b5f9cbc083b764b6476f547879",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3801,9 +3592,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/detector/issues",
|
||||
"source": "https://github.com/utopia-php/detector/tree/0.1.2"
|
||||
"source": "https://github.com/utopia-php/detector/tree/0.1.4"
|
||||
},
|
||||
"time": "2025-03-11T13:01:25+00:00"
|
||||
"time": "2025-04-09T11:50:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
|
@ -3914,16 +3705,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/fetch",
|
||||
"version": "0.3.1",
|
||||
"version": "0.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/fetch.git",
|
||||
"reference": "524dd50afa8c64670c4fb18f1df4db9b5bb4b3d0"
|
||||
"reference": "65095dac14037db0c822fb5e209e5bd3187a0303"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/fetch/zipball/524dd50afa8c64670c4fb18f1df4db9b5bb4b3d0",
|
||||
"reference": "524dd50afa8c64670c4fb18f1df4db9b5bb4b3d0",
|
||||
"url": "https://api.github.com/repos/utopia-php/fetch/zipball/65095dac14037db0c822fb5e209e5bd3187a0303",
|
||||
"reference": "65095dac14037db0c822fb5e209e5bd3187a0303",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3947,9 +3738,9 @@
|
|||
"description": "A simple library that provides an interface for making HTTP Requests.",
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/fetch/issues",
|
||||
"source": "https://github.com/utopia-php/fetch/tree/0.3.1"
|
||||
"source": "https://github.com/utopia-php/fetch/tree/0.4.1"
|
||||
},
|
||||
"time": "2025-03-05T18:08:55+00:00"
|
||||
"time": "2025-04-14T07:34:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
|
|
@ -4000,16 +3791,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.8.0",
|
||||
"version": "0.8.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "dcae5b1c6deb3ff6865f4e68f012b3709c289bca"
|
||||
"reference": "6c736965177f9a9e71311e22b80cfa88511768e9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/dcae5b1c6deb3ff6865f4e68f012b3709c289bca",
|
||||
"reference": "dcae5b1c6deb3ff6865f4e68f012b3709c289bca",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/6c736965177f9a9e71311e22b80cfa88511768e9",
|
||||
"reference": "6c736965177f9a9e71311e22b80cfa88511768e9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4043,9 +3834,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.8.0"
|
||||
"source": "https://github.com/utopia-php/image/tree/0.8.2"
|
||||
},
|
||||
"time": "2025-02-20T11:49:03+00:00"
|
||||
"time": "2025-04-08T11:31:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
|
|
@ -4205,16 +3996,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.8.1",
|
||||
"version": "0.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab"
|
||||
"reference": "84163e16edc0b2e64c34ad7b7c4cc5f05d762daf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab",
|
||||
"reference": "36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/84163e16edc0b2e64c34ad7b7c4cc5f05d762daf",
|
||||
"reference": "84163e16edc0b2e64c34ad7b7c4cc5f05d762daf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4222,7 +4013,7 @@
|
|||
"ext-curl": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": ">=8.1",
|
||||
"utopia-php/database": "0.61.*",
|
||||
"utopia-php/database": "0.*.*",
|
||||
"utopia-php/dsn": "0.2.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/storage": "0.18.*"
|
||||
|
|
@ -4255,69 +4046,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.8.1"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.8.6"
|
||||
},
|
||||
"time": "2025-03-18T07:48:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
"version": "0.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/mongo.git",
|
||||
"reference": "52326a9a43e2d27ff0c15c48ba746dacbe9a7aee"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/mongo/zipball/52326a9a43e2d27ff0c15c48ba746dacbe9a7aee",
|
||||
"reference": "52326a9a43e2d27ff0c15c48ba746dacbe9a7aee",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mongodb": "*",
|
||||
"mongodb/mongodb": "1.10.0",
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.14",
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.8.*",
|
||||
"phpunit/phpunit": "^9.4",
|
||||
"swoole/ide-helper": "4.8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\Mongo\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
},
|
||||
{
|
||||
"name": "Wess",
|
||||
"email": "wess@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to manage Mongo database",
|
||||
"keywords": [
|
||||
"database",
|
||||
"mongo",
|
||||
"php",
|
||||
"upf",
|
||||
"utopia"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/mongo/issues",
|
||||
"source": "https://github.com/utopia-php/mongo/tree/0.3.1"
|
||||
},
|
||||
"time": "2023-09-01T17:25:28+00:00"
|
||||
"time": "2025-04-14T08:22:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/orchestration",
|
||||
|
|
@ -4421,16 +4152,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
"version": "0.7.0",
|
||||
"version": "0.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/pools.git",
|
||||
"reference": "ad64d45afda08ec8b29e2642a8d18075964d40bf"
|
||||
"reference": "60733929dc328e7ea47e800579c8bbf0d49df5ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/ad64d45afda08ec8b29e2642a8d18075964d40bf",
|
||||
"reference": "ad64d45afda08ec8b29e2642a8d18075964d40bf",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/60733929dc328e7ea47e800579c8bbf0d49df5ba",
|
||||
"reference": "60733929dc328e7ea47e800579c8bbf0d49df5ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4467,9 +4198,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/pools/issues",
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.7.0"
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.8.0"
|
||||
},
|
||||
"time": "2025-03-18T03:55:33+00:00"
|
||||
"time": "2025-03-19T10:22:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/preloader",
|
||||
|
|
@ -4526,23 +4257,23 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/queue",
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/queue.git",
|
||||
"reference": "077075f1d57afa430f76c35ed3bf4616e0eee8e7"
|
||||
"reference": "32b6f84c55aae761db5a5ae76cc91ca8dbc8bc32"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/077075f1d57afa430f76c35ed3bf4616e0eee8e7",
|
||||
"reference": "077075f1d57afa430f76c35ed3bf4616e0eee8e7",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/32b6f84c55aae761db5a5ae76cc91ca8dbc8bc32",
|
||||
"reference": "32b6f84c55aae761db5a5ae76cc91ca8dbc8bc32",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"php-amqplib/php-amqplib": "^3.7",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/fetch": "^0.3.0",
|
||||
"utopia-php/fetch": "0.4.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
},
|
||||
|
|
@ -4585,9 +4316,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/queue/issues",
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.9.0"
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.9.1"
|
||||
},
|
||||
"time": "2025-03-13T12:22:41+00:00"
|
||||
"time": "2025-03-28T19:49:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
|
|
@ -4700,16 +4431,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
"version": "0.8.2",
|
||||
"version": "0.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/swoole.git",
|
||||
"reference": "5fa9d42c608ad46a4ce42a6d2b2eae00592fccd4"
|
||||
"reference": "1af73dd3e73987cf729c7db399054e4a70befd99"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/5fa9d42c608ad46a4ce42a6d2b2eae00592fccd4",
|
||||
"reference": "5fa9d42c608ad46a4ce42a6d2b2eae00592fccd4",
|
||||
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/1af73dd3e73987cf729c7db399054e4a70befd99",
|
||||
"reference": "1af73dd3e73987cf729c7db399054e4a70befd99",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4745,9 +4476,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/swoole/issues",
|
||||
"source": "https://github.com/utopia-php/swoole/tree/0.8.2"
|
||||
"source": "https://github.com/utopia-php/swoole/tree/0.8.3"
|
||||
},
|
||||
"time": "2024-02-01T14:54:12+00:00"
|
||||
"time": "2025-03-26T10:09:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/system",
|
||||
|
|
@ -4906,27 +4637,28 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
"version": "0.1.0",
|
||||
"version": "0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/websocket.git",
|
||||
"reference": "51fcb86171400d8aa40d76c54593481fd273dab5"
|
||||
"reference": "629e53640b108eab43c7cc9ab375efade8622d43"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/websocket/zipball/51fcb86171400d8aa40d76c54593481fd273dab5",
|
||||
"reference": "51fcb86171400d8aa40d76c54593481fd273dab5",
|
||||
"url": "https://api.github.com/repos/utopia-php/websocket/zipball/629e53640b108eab43c7cc9ab375efade8622d43",
|
||||
"reference": "629e53640b108eab43c7cc9ab375efade8622d43",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.15",
|
||||
"phpstan/phpstan": "^1.12",
|
||||
"phpunit/phpunit": "^9.5.5",
|
||||
"swoole/ide-helper": "4.6.6",
|
||||
"swoole/ide-helper": "5.1.2",
|
||||
"textalk/websocket": "1.5.2",
|
||||
"vimeo/psalm": "^4.8.1",
|
||||
"workerman/workerman": "^4.0"
|
||||
"workerman/workerman": "4.1.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
|
@ -4938,16 +4670,6 @@
|
|||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
},
|
||||
{
|
||||
"name": "Torsten Dittmann",
|
||||
"email": "torsten@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple abstraction for WebSocket servers.",
|
||||
"keywords": [
|
||||
"framework",
|
||||
|
|
@ -4958,9 +4680,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/websocket/issues",
|
||||
"source": "https://github.com/utopia-php/websocket/tree/0.1.0"
|
||||
"source": "https://github.com/utopia-php/websocket/tree/0.3.0"
|
||||
},
|
||||
"time": "2021-12-20T10:50:09+00:00"
|
||||
"time": "2025-03-28T01:11:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
|
|
@ -5089,16 +4811,16 @@
|
|||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.40.9",
|
||||
"version": "0.40.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "dbb45a5db22cdc3368fe2573c07ba6088f188fa4"
|
||||
"reference": "0ec5f4a60c15e33e208bc3444ba6148b1d0f0027"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/dbb45a5db22cdc3368fe2573c07ba6088f188fa4",
|
||||
"reference": "dbb45a5db22cdc3368fe2573c07ba6088f188fa4",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0ec5f4a60c15e33e208bc3444ba6148b1d0f0027",
|
||||
"reference": "0ec5f4a60c15e33e208bc3444ba6148b1d0f0027",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5134,9 +4856,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.9"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.11"
|
||||
},
|
||||
"time": "2025-03-17T18:39:14+00:00"
|
||||
"time": "2025-03-26T10:53:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
|
@ -5363,16 +5085,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/pint",
|
||||
"version": "v1.21.2",
|
||||
"version": "v1.22.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/pint.git",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558"
|
||||
"reference": "7ddfaa6523a675fae5c4123ee38fc6bfb8ee4f36"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/7ddfaa6523a675fae5c4123ee38fc6bfb8ee4f36",
|
||||
"reference": "7ddfaa6523a675fae5c4123ee38fc6bfb8ee4f36",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5383,9 +5105,9 @@
|
|||
"php": "^8.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.72.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.75.0",
|
||||
"illuminate/view": "^11.44.2",
|
||||
"larastan/larastan": "^3.2.0",
|
||||
"larastan/larastan": "^3.3.1",
|
||||
"laravel-zero/framework": "^11.36.1",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/termwind": "^2.3",
|
||||
|
|
@ -5425,7 +5147,7 @@
|
|||
"issues": "https://github.com/laravel/pint/issues",
|
||||
"source": "https://github.com/laravel/pint"
|
||||
},
|
||||
"time": "2025-03-14T22:31:42+00:00"
|
||||
"time": "2025-04-08T22:11:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
|
@ -7527,16 +7249,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v7.2.1",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3"
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"reference": "e51498ea18570c062e7df29d05a7003585b19b88",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -7600,7 +7322,7 @@
|
|||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.1"
|
||||
"source": "https://github.com/symfony/console/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -7616,7 +7338,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-11T03:49:26+00:00"
|
||||
"time": "2025-03-12T08:11:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
|
|
@ -8131,16 +7853,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v7.2.4",
|
||||
"version": "v7.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf"
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf",
|
||||
"reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -8172,7 +7894,7 @@
|
|||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.4"
|
||||
"source": "https://github.com/symfony/process/tree/v7.2.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -8188,7 +7910,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-02-05T08:33:46+00:00"
|
||||
"time": "2025-03-13T12:21:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ services:
|
|||
- _APP_OPTIONS_COMPUTE_FORCE_HTTPS
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
|
|
@ -160,7 +162,8 @@ services:
|
|||
- _APP_STORAGE_WASABI_REGION
|
||||
- _APP_STORAGE_WASABI_BUCKET
|
||||
- _APP_COMPUTE_SIZE_LIMIT
|
||||
- _APP_COMPUTE_TIMEOUT
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_SITES_TIMEOUT
|
||||
- _APP_COMPUTE_BUILD_TIMEOUT
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
|
|
@ -175,6 +178,7 @@ services:
|
|||
- _APP_MAINTENANCE_RETENTION_CACHE
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
|
||||
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
- _APP_SMS_PROVIDER
|
||||
|
|
@ -201,11 +205,13 @@ services:
|
|||
- _APP_DATABASE_SHARED_TABLES_V1
|
||||
- _APP_DATABASE_SHARED_NAMESPACE
|
||||
- _APP_FUNCTIONS_CREATION_ABUSE_LIMIT
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: appwrite/console:5.3.0-sites-rc.28
|
||||
image: appwrite/console:5.3.0-sites-rc.40
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
|
@ -394,6 +400,8 @@ services:
|
|||
- _APP_DATABASE_SHARED_TABLES
|
||||
- _APP_DATABASE_SHARED_TABLES_V1
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
|
||||
|
||||
appwrite-worker-databases:
|
||||
entrypoint: worker-databases
|
||||
|
|
@ -462,7 +470,8 @@ services:
|
|||
- _APP_VCS_GITHUB_APP_NAME
|
||||
- _APP_VCS_GITHUB_PRIVATE_KEY
|
||||
- _APP_VCS_GITHUB_APP_ID
|
||||
- _APP_COMPUTE_TIMEOUT
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_SITES_TIMEOUT
|
||||
- _APP_COMPUTE_BUILD_TIMEOUT
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
|
|
@ -494,6 +503,8 @@ services:
|
|||
- _APP_STORAGE_WASABI_BUCKET
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
- _APP_DOMAIN_SITES
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
|
||||
appwrite-worker-certificates:
|
||||
entrypoint: worker-certificates
|
||||
|
|
@ -515,7 +526,9 @@ services:
|
|||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
- _APP_REDIS_HOST
|
||||
|
|
@ -559,7 +572,8 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_COMPUTE_TIMEOUT
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_SITES_TIMEOUT
|
||||
- _APP_COMPUTE_BUILD_TIMEOUT
|
||||
- _APP_COMPUTE_CPUS
|
||||
- _APP_COMPUTE_MEMORY
|
||||
|
|
@ -680,7 +694,9 @@ services:
|
|||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_EMAIL_SECURITY
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
|
|
@ -712,7 +728,9 @@ services:
|
|||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_REDIS_HOST
|
||||
|
|
@ -729,6 +747,7 @@ services:
|
|||
- _APP_MAINTENANCE_RETENTION_CACHE
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE
|
||||
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
- _APP_MAINTENANCE_DELAY
|
||||
|
|
@ -961,7 +980,7 @@ services:
|
|||
hostname: exc1
|
||||
<<: *x-logging
|
||||
stop_signal: SIGINT
|
||||
image: openruntimes/executor:0.7.12
|
||||
image: openruntimes/executor:0.7.13
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
|
@ -1144,4 +1163,4 @@ volumes:
|
|||
appwrite-functions:
|
||||
appwrite-sites:
|
||||
appwrite-builds:
|
||||
appwrite-config:
|
||||
appwrite-config:
|
||||
|
|
|
|||
BIN
public/images/sites/templates/docusaurus-dark.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
public/images/sites/templates/docusaurus-light.png
Normal file
|
After Width: | Height: | Size: 81 KiB |
BIN
public/images/sites/templates/lynx-starter-dark.png
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
public/images/sites/templates/lynx-starter-light.png
Normal file
|
After Width: | Height: | Size: 323 KiB |
BIN
public/images/sites/templates/starter-for-analog-dark.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/images/sites/templates/starter-for-analog-light.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
public/images/sites/templates/starter-for-astro-dark.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
public/images/sites/templates/starter-for-astro-light.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
public/images/sites/templates/starter-for-remix-dark.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
public/images/sites/templates/starter-for-remix-light.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 118 KiB |
|
After Width: | Height: | Size: 118 KiB |
BIN
public/images/sites/templates/vitepress-dark.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
public/images/sites/templates/vitepress-light.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
public/images/sites/templates/vuepress-dark.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
public/images/sites/templates/vuepress-light.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
18
public/images/vcs/qr-dark.svg
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="path-1-outside-1_6367_338401" maskUnits="userSpaceOnUse" x="0" y="0" width="30" height="30" fill="black">
|
||||
<rect fill="white" width="30" height="30"/>
|
||||
<path d="M1 10.6C1 7.23969 1 5.55953 1.65396 4.27606C2.2292 3.14708 3.14708 2.2292 4.27606 1.65396C5.55953 1 7.23969 1 10.6 1H19.4C22.7603 1 24.4405 1 25.7239 1.65396C26.8529 2.2292 27.7708 3.14708 28.346 4.27606C29 5.55953 29 7.23969 29 10.6V19.4C29 22.7603 29 24.4405 28.346 25.7239C27.7708 26.8529 26.8529 27.7708 25.7239 28.346C24.4405 29 22.7603 29 19.4 29H10.6C7.23969 29 5.55953 29 4.27606 28.346C3.14708 27.7708 2.2292 26.8529 1.65396 25.7239C1 24.4405 1 22.7603 1 19.4V10.6Z"/>
|
||||
</mask>
|
||||
<path d="M1 10.6C1 7.23969 1 5.55953 1.65396 4.27606C2.2292 3.14708 3.14708 2.2292 4.27606 1.65396C5.55953 1 7.23969 1 10.6 1H19.4C22.7603 1 24.4405 1 25.7239 1.65396C26.8529 2.2292 27.7708 3.14708 28.346 4.27606C29 5.55953 29 7.23969 29 10.6V19.4C29 22.7603 29 24.4405 28.346 25.7239C27.7708 26.8529 26.8529 27.7708 25.7239 28.346C24.4405 29 22.7603 29 19.4 29H10.6C7.23969 29 5.55953 29 4.27606 28.346C3.14708 27.7708 2.2292 26.8529 1.65396 25.7239C1 24.4405 1 22.7603 1 19.4V10.6Z" fill="#1D1D21"/>
|
||||
<path d="M4.27606 28.346L4.73005 27.455L4.27606 28.346ZM1.65396 25.7239L0.762954 26.1779L1.65396 25.7239ZM28.346 25.7239L29.237 26.1779L28.346 25.7239ZM25.7239 28.346L26.1779 29.237L25.7239 28.346ZM28.346 4.27606L27.455 4.73005L28.346 4.27606ZM10.6 2H19.4V0H10.6V2ZM28 10.6V19.4H30V10.6H28ZM19.4 28H10.6V30H19.4V28ZM2 19.4V10.6H0V19.4H2ZM10.6 28C8.90334 28 7.69099 27.9992 6.74064 27.9216C5.80197 27.8449 5.20731 27.6982 4.73005 27.455L3.82207 29.237C4.62827 29.6478 5.51543 29.8281 6.57778 29.9149C7.62846 30.0008 8.93634 30 10.6 30V28ZM0 19.4C0 21.0637 -0.000777706 22.3715 0.0850662 23.4222C0.171864 24.4846 0.352173 25.3717 0.762954 26.1779L2.54497 25.27C2.30179 24.7927 2.15512 24.198 2.07842 23.2594C2.00078 22.309 2 21.0967 2 19.4H0ZM4.73005 27.455C3.78924 26.9757 3.02433 26.2108 2.54497 25.27L0.762954 26.1779C1.43407 27.4951 2.50493 28.5659 3.82207 29.237L4.73005 27.455ZM28 19.4C28 21.0967 27.9992 22.309 27.9216 23.2594C27.8449 24.198 27.6982 24.7927 27.455 25.27L29.237 26.1779C29.6478 25.3717 29.8281 24.4846 29.9149 23.4222C30.0008 22.3715 30 21.0637 30 19.4H28ZM19.4 30C21.0637 30 22.3715 30.0008 23.4222 29.9149C24.4846 29.8281 25.3717 29.6478 26.1779 29.237L25.27 27.455C24.7927 27.6982 24.198 27.8449 23.2594 27.9216C22.309 27.9992 21.0967 28 19.4 28V30ZM27.455 25.27C26.9757 26.2108 26.2108 26.9757 25.27 27.455L26.1779 29.237C27.4951 28.5659 28.5659 27.4951 29.237 26.1779L27.455 25.27ZM19.4 2C21.0967 2 22.309 2.00078 23.2594 2.07842C24.198 2.15512 24.7927 2.30179 25.27 2.54497L26.1779 0.762954C25.3717 0.352173 24.4846 0.171864 23.4222 0.0850662C22.3715 -0.000777706 21.0637 0 19.4 0V2ZM30 10.6C30 8.93634 30.0008 7.62846 29.9149 6.57778C29.8281 5.51543 29.6478 4.62827 29.237 3.82207L27.455 4.73005C27.6982 5.20731 27.8449 5.80197 27.9216 6.74064C27.9992 7.69099 28 8.90334 28 10.6H30ZM25.27 2.54497C26.2108 3.02433 26.9757 3.78924 27.455 4.73005L29.237 3.82207C28.5659 2.50493 27.4951 1.43407 26.1779 0.762954L25.27 2.54497ZM10.6 0C8.93634 0 7.62846 -0.000777706 6.57778 0.0850662C5.51543 0.171864 4.62827 0.352173 3.82207 0.762954L4.73005 2.54497C5.20731 2.30179 5.80197 2.15512 6.74064 2.07842C7.69099 2.00078 8.90334 2 10.6 2V0ZM2 10.6C2 8.90334 2.00078 7.69099 2.07842 6.74064C2.15512 5.80197 2.30179 5.20731 2.54497 4.73005L0.762954 3.82207C0.352173 4.62827 0.171864 5.51543 0.0850662 6.57778C-0.000777706 7.62846 0 8.93634 0 10.6H2ZM3.82207 0.762954C2.50493 1.43407 1.43407 2.50493 0.762954 3.82207L2.54497 4.73005C3.02433 3.78924 3.78924 3.02433 4.73005 2.54497L3.82207 0.762954Z" fill="#414146" mask="url(#path-1-outside-1_6367_338401)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 9C8 8.44772 8.44772 8 9 8H12C12.5523 8 13 8.44772 13 9V12C13 12.5523 12.5523 13 12 13H9C8.44772 13 8 12.5523 8 12V9ZM10 11V10H11V11H10Z" fill="#818186"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 18C8 17.4477 8.44772 17 9 17H12C12.5523 17 13 17.4477 13 18V21C13 21.5523 12.5523 22 12 22H9C8.44772 22 8 21.5523 8 21V18ZM10 20V19H11V20H10Z" fill="#818186"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 8C17.4477 8 17 8.44772 17 9V12C17 12.5523 17.4477 13 18 13H21C21.5523 13 22 12.5523 22 12V9C22 8.44772 21.5523 8 21 8H18ZM19 10V11H20V10H19Z" fill="#818186"/>
|
||||
<path d="M16 9C16 8.44772 15.5523 8 15 8C14.4477 8 14 8.44772 14 9V10C14 10.5523 14.4477 11 15 11C15.5523 11 16 10.5523 16 10V9Z" fill="#818186"/>
|
||||
<path d="M15 12C15.5523 12 16 12.4477 16 13V14H18C18.5523 14 19 14.4477 19 15C19 15.5523 18.5523 16 18 16H15C14.4477 16 14 15.5523 14 15V13C14 12.4477 14.4477 12 15 12Z" fill="#818186"/>
|
||||
<path d="M21 14C20.4477 14 20 14.4477 20 15C20 15.5523 20.4477 16 21 16C21.5523 16 22 15.5523 22 15C22 14.4477 21.5523 14 21 14Z" fill="#818186"/>
|
||||
<path d="M14 18C14 17.4477 14.4477 17 15 17H16C16.5523 17 17 17.4477 17 18C17 18.5523 16.5523 19 16 19V21C16 21.5523 15.5523 22 15 22C14.4477 22 14 21.5523 14 21V18Z" fill="#818186"/>
|
||||
<path d="M12 16C12.5523 16 13 15.5523 13 15C13 14.4477 12.5523 14 12 14H9C8.44772 14 8 14.4477 8 15C8 15.5523 8.44772 16 9 16H12Z" fill="#818186"/>
|
||||
<path d="M22 18C22 18.5523 21.5523 19 21 19H19C18.4477 19 18 18.5523 18 18C18 17.4477 18.4477 17 19 17H21C21.5523 17 22 17.4477 22 18Z" fill="#818186"/>
|
||||
<path d="M21 22C21.5523 22 22 21.5523 22 21C22 20.4477 21.5523 20 21 20H18C17.4477 20 17 20.4477 17 21C17 21.5523 17.4477 22 18 22H21Z" fill="#818186"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.5 KiB |
18
public/images/vcs/qr-light.svg
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="path-1-outside-1_6367_338394" maskUnits="userSpaceOnUse" x="0" y="0" width="30" height="30" fill="black">
|
||||
<rect fill="white" width="30" height="30"/>
|
||||
<path d="M1 10.6C1 7.23969 1 5.55953 1.65396 4.27606C2.2292 3.14708 3.14708 2.2292 4.27606 1.65396C5.55953 1 7.23969 1 10.6 1H19.4C22.7603 1 24.4405 1 25.7239 1.65396C26.8529 2.2292 27.7708 3.14708 28.346 4.27606C29 5.55953 29 7.23969 29 10.6V19.4C29 22.7603 29 24.4405 28.346 25.7239C27.7708 26.8529 26.8529 27.7708 25.7239 28.346C24.4405 29 22.7603 29 19.4 29H10.6C7.23969 29 5.55953 29 4.27606 28.346C3.14708 27.7708 2.2292 26.8529 1.65396 25.7239C1 24.4405 1 22.7603 1 19.4V10.6Z"/>
|
||||
</mask>
|
||||
<path d="M1 10.6C1 7.23969 1 5.55953 1.65396 4.27606C2.2292 3.14708 3.14708 2.2292 4.27606 1.65396C5.55953 1 7.23969 1 10.6 1H19.4C22.7603 1 24.4405 1 25.7239 1.65396C26.8529 2.2292 27.7708 3.14708 28.346 4.27606C29 5.55953 29 7.23969 29 10.6V19.4C29 22.7603 29 24.4405 28.346 25.7239C27.7708 26.8529 26.8529 27.7708 25.7239 28.346C24.4405 29 22.7603 29 19.4 29H10.6C7.23969 29 5.55953 29 4.27606 28.346C3.14708 27.7708 2.2292 26.8529 1.65396 25.7239C1 24.4405 1 22.7603 1 19.4V10.6Z" fill="white"/>
|
||||
<path d="M4.27606 28.346L4.73005 27.455L4.27606 28.346ZM1.65396 25.7239L0.762954 26.1779L1.65396 25.7239ZM28.346 25.7239L29.237 26.1779L28.346 25.7239ZM25.7239 28.346L26.1779 29.237L25.7239 28.346ZM28.346 4.27606L27.455 4.73005L28.346 4.27606ZM10.6 2H19.4V0H10.6V2ZM28 10.6V19.4H30V10.6H28ZM19.4 28H10.6V30H19.4V28ZM2 19.4V10.6H0V19.4H2ZM10.6 28C8.90334 28 7.69099 27.9992 6.74064 27.9216C5.80197 27.8449 5.20731 27.6982 4.73005 27.455L3.82207 29.237C4.62827 29.6478 5.51543 29.8281 6.57778 29.9149C7.62846 30.0008 8.93634 30 10.6 30V28ZM0 19.4C0 21.0637 -0.000777706 22.3715 0.0850662 23.4222C0.171864 24.4846 0.352173 25.3717 0.762954 26.1779L2.54497 25.27C2.30179 24.7927 2.15512 24.198 2.07842 23.2594C2.00078 22.309 2 21.0967 2 19.4H0ZM4.73005 27.455C3.78924 26.9757 3.02433 26.2108 2.54497 25.27L0.762954 26.1779C1.43407 27.4951 2.50493 28.5659 3.82207 29.237L4.73005 27.455ZM28 19.4C28 21.0967 27.9992 22.309 27.9216 23.2594C27.8449 24.198 27.6982 24.7927 27.455 25.27L29.237 26.1779C29.6478 25.3717 29.8281 24.4846 29.9149 23.4222C30.0008 22.3715 30 21.0637 30 19.4H28ZM19.4 30C21.0637 30 22.3715 30.0008 23.4222 29.9149C24.4846 29.8281 25.3717 29.6478 26.1779 29.237L25.27 27.455C24.7927 27.6982 24.198 27.8449 23.2594 27.9216C22.309 27.9992 21.0967 28 19.4 28V30ZM27.455 25.27C26.9757 26.2108 26.2108 26.9757 25.27 27.455L26.1779 29.237C27.4951 28.5659 28.5659 27.4951 29.237 26.1779L27.455 25.27ZM19.4 2C21.0967 2 22.309 2.00078 23.2594 2.07842C24.198 2.15512 24.7927 2.30179 25.27 2.54497L26.1779 0.762954C25.3717 0.352173 24.4846 0.171864 23.4222 0.0850662C22.3715 -0.000777706 21.0637 0 19.4 0V2ZM30 10.6C30 8.93634 30.0008 7.62846 29.9149 6.57778C29.8281 5.51543 29.6478 4.62827 29.237 3.82207L27.455 4.73005C27.6982 5.20731 27.8449 5.80197 27.9216 6.74064C27.9992 7.69099 28 8.90334 28 10.6H30ZM25.27 2.54497C26.2108 3.02433 26.9757 3.78924 27.455 4.73005L29.237 3.82207C28.5659 2.50493 27.4951 1.43407 26.1779 0.762954L25.27 2.54497ZM10.6 0C8.93634 0 7.62846 -0.000777706 6.57778 0.0850662C5.51543 0.171864 4.62827 0.352173 3.82207 0.762954L4.73005 2.54497C5.20731 2.30179 5.80197 2.15512 6.74064 2.07842C7.69099 2.00078 8.90334 2 10.6 2V0ZM2 10.6C2 8.90334 2.00078 7.69099 2.07842 6.74064C2.15512 5.80197 2.30179 5.20731 2.54497 4.73005L0.762954 3.82207C0.352173 4.62827 0.171864 5.51543 0.0850662 6.57778C-0.000777706 7.62846 0 8.93634 0 10.6H2ZM3.82207 0.762954C2.50493 1.43407 1.43407 2.50493 0.762954 3.82207L2.54497 4.73005C3.02433 3.78924 3.78924 3.02433 4.73005 2.54497L3.82207 0.762954Z" fill="#D8D8DB" mask="url(#path-1-outside-1_6367_338394)"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 9C8 8.44772 8.44772 8 9 8H12C12.5523 8 13 8.44772 13 9V12C13 12.5523 12.5523 13 12 13H9C8.44772 13 8 12.5523 8 12V9ZM10 11V10H11V11H10Z" fill="#97979B"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 18C8 17.4477 8.44772 17 9 17H12C12.5523 17 13 17.4477 13 18V21C13 21.5523 12.5523 22 12 22H9C8.44772 22 8 21.5523 8 21V18ZM10 20V19H11V20H10Z" fill="#97979B"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 8C17.4477 8 17 8.44772 17 9V12C17 12.5523 17.4477 13 18 13H21C21.5523 13 22 12.5523 22 12V9C22 8.44772 21.5523 8 21 8H18ZM19 10V11H20V10H19Z" fill="#97979B"/>
|
||||
<path d="M16 9C16 8.44772 15.5523 8 15 8C14.4477 8 14 8.44772 14 9V10C14 10.5523 14.4477 11 15 11C15.5523 11 16 10.5523 16 10V9Z" fill="#97979B"/>
|
||||
<path d="M15 12C15.5523 12 16 12.4477 16 13V14H18C18.5523 14 19 14.4477 19 15C19 15.5523 18.5523 16 18 16H15C14.4477 16 14 15.5523 14 15V13C14 12.4477 14.4477 12 15 12Z" fill="#97979B"/>
|
||||
<path d="M21 14C20.4477 14 20 14.4477 20 15C20 15.5523 20.4477 16 21 16C21.5523 16 22 15.5523 22 15C22 14.4477 21.5523 14 21 14Z" fill="#97979B"/>
|
||||
<path d="M14 18C14 17.4477 14.4477 17 15 17H16C16.5523 17 17 17.4477 17 18C17 18.5523 16.5523 19 16 19V21C16 21.5523 15.5523 22 15 22C14.4477 22 14 21.5523 14 21V18Z" fill="#97979B"/>
|
||||
<path d="M12 16C12.5523 16 13 15.5523 13 15C13 14.4477 12.5523 14 12 14H9C8.44772 14 8 14.4477 8 15C8 15.5523 8.44772 16 9 16H12Z" fill="#97979B"/>
|
||||
<path d="M22 18C22 18.5523 21.5523 19 21 19H19C18.4477 19 18 18.5523 18 18C18 17.4477 18.4477 17 19 17H21C21.5523 17 22 17.4477 22 18Z" fill="#97979B"/>
|
||||
<path d="M21 22C21.5523 22 22 21.5523 22 21C22 20.4477 21.5523 20 21 20H18C17.4477 20 17 20.4477 17 21C17 21.5523 17.4477 22 18 22H21Z" fill="#97979B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
BIN
public/images/vcs/status-building-dark.gif
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
public/images/vcs/status-building-light.gif
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
public/images/vcs/status-failed-dark.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
public/images/vcs/status-failed-light.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
public/images/vcs/status-ready-dark.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
public/images/vcs/status-ready-light.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
public/images/vcs/status-waiting-dark.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
public/images/vcs/status-waiting-light.png
Normal file
|
After Width: | Height: | Size: 4.5 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(
|
||||
|
|
|
|||
|
|
@ -174,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';
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ abstract class Migration
|
|||
'1.6.0' => 'V21',
|
||||
'1.6.1' => 'V21',
|
||||
'1.6.2' => 'V22',
|
||||
'1.7.0' => 'V23',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ use Utopia\Database\DateTime;
|
|||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\System\System;
|
||||
|
||||
class V19 extends Migration
|
||||
{
|
||||
|
|
@ -731,7 +730,7 @@ class V19 extends Migration
|
|||
|
||||
if (empty($document->getAttribute('scheduleId', null))) {
|
||||
$schedule = $this->consoleDB->createDocument('schedules', new Document([
|
||||
'region' => System::getEnv('_APP_REGION', 'default'), // Todo replace with projects region
|
||||
'region' => $project->getAttribute('region'),
|
||||
'resourceType' => 'function',
|
||||
'resourceId' => $document->getId(),
|
||||
'resourceInternalId' => $document->getInternalId(),
|
||||
|
|
|
|||
69
src/Appwrite/Migration/Version/V23.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Migration\Version;
|
||||
|
||||
use Appwrite\Migration\Migration;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
|
||||
class V23 extends Migration
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
/**
|
||||
* Disable SubQueries for Performance.
|
||||
*/
|
||||
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
||||
Database::addFilter(
|
||||
$name,
|
||||
fn () => null,
|
||||
fn () => []
|
||||
);
|
||||
}
|
||||
|
||||
Console::info('Migrating Collections');
|
||||
$this->migrateCollections();
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate Collections.
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception|Throwable
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
$collectionType = match ($internalProjectId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
|
||||
$collections = $this->collections[$collectionType];
|
||||
foreach ($collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
Console::log("Migrating Collection \"{$id}\"");
|
||||
|
||||
$this->projectDB->setNamespace("_$internalProjectId");
|
||||
|
||||
switch ($id) {
|
||||
case 'memberships':
|
||||
// Create roles index
|
||||
try {
|
||||
$this->createIndexFromCollection($this->projectDB, $id, '_key_roles');
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'_key_roles' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,24 +4,22 @@ namespace Appwrite\Network\Validator;
|
|||
|
||||
use Utopia\Validator;
|
||||
|
||||
class CNAME extends Validator
|
||||
class DNS extends Validator
|
||||
{
|
||||
public const RECORD_A = 'a';
|
||||
public const RECORD_AAAA = 'aaaa';
|
||||
public const RECORD_CNAME = 'cname';
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected mixed $logs;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $target;
|
||||
|
||||
/**
|
||||
* @param string $target
|
||||
*/
|
||||
public function __construct($target)
|
||||
public function __construct(protected $target, protected string $type = self::RECORD_CNAME)
|
||||
{
|
||||
$this->target = $target;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -29,7 +27,7 @@ class CNAME extends Validator
|
|||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Invalid CNAME record';
|
||||
return 'Invalid DNS record';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -41,20 +39,34 @@ class CNAME extends Validator
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if CNAME record target value matches selected target
|
||||
* Check if DNS record value matches specific value
|
||||
*
|
||||
* @param mixed $domain
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($domain): bool
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (!is_string($domain)) {
|
||||
$typeNative = match ($this->type) {
|
||||
self::RECORD_A => DNS_A,
|
||||
self::RECORD_AAAA => DNS_AAAA,
|
||||
self::RECORD_CNAME => DNS_CNAME,
|
||||
default => throw new \Exception('Record type not supported.')
|
||||
};
|
||||
|
||||
$dnsKey = match ($this->type) {
|
||||
self::RECORD_A => 'ip',
|
||||
self::RECORD_AAAA => 'ipv6',
|
||||
self::RECORD_CNAME => 'target',
|
||||
default => throw new \Exception('Record type not supported.')
|
||||
};
|
||||
|
||||
if (!is_string($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$records = \dns_get_record($domain, DNS_CNAME);
|
||||
$records = \dns_get_record($value, $typeNative);
|
||||
$this->logs = $records;
|
||||
} catch (\Throwable $th) {
|
||||
return false;
|
||||
|
|
@ -65,7 +77,7 @@ class CNAME extends Validator
|
|||
}
|
||||
|
||||
foreach ($records as $record) {
|
||||
if (isset($record['target']) && $record['target'] === $this->target) {
|
||||
if (isset($record[$dnsKey]) && $record[$dnsKey] === $this->target) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -171,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(),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use Appwrite\SDK\Method;
|
|||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Executor\Executor;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
|
|
@ -58,6 +57,7 @@ class Update extends Action
|
|||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('executor')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,8 @@ class Update extends Action
|
|||
Response $response,
|
||||
Database $dbForProject,
|
||||
Document $project,
|
||||
Event $queueForEvents
|
||||
Event $queueForEvents,
|
||||
Executor $executor
|
||||
) {
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
|
|
@ -101,7 +102,6 @@ class Update extends Action
|
|||
}
|
||||
|
||||
try {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
$executor->deleteRuntime($project->getId(), $deploymentId . "-build");
|
||||
} catch (\Throwable $th) {
|
||||
// Don't throw if the deployment doesn't exist
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ class Create extends Base
|
|||
->inject('queueForStatsUsage')
|
||||
->inject('queueForFunctions')
|
||||
->inject('geodb')
|
||||
->inject('executor')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -113,7 +114,8 @@ class Create extends Base
|
|||
Event $queueForEvents,
|
||||
StatsUsage $queueForStatsUsage,
|
||||
Func $queueForFunctions,
|
||||
Reader $geodb
|
||||
Reader $geodb,
|
||||
Executor $executor
|
||||
) {
|
||||
$async = \strval($async) === 'true' || \strval($async) === '1';
|
||||
|
||||
|
|
@ -381,7 +383,6 @@ class Create extends Base
|
|||
]);
|
||||
|
||||
/** Execute function */
|
||||
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
|
||||
try {
|
||||
$version = $function->getAttribute('version', 'v2');
|
||||
$command = $runtime['startCommand'];
|
||||
|
|
|
|||
|
|
@ -74,9 +74,9 @@ class Create extends Base
|
|||
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of role strings with execution permissions. By default no user is granted with any execute permissions. [learn more about roles](https://appwrite.io/docs/permissions#permission-roles). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.', true)
|
||||
->param('events', [], new ArrayList(new FunctionEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true)
|
||||
->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('timeout', 15, new Range(1, (int) System::getEnv('_APP_FUNCTIONS_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)
|
||||
|
|
|
|||
|
|
@ -78,9 +78,9 @@ class Update extends Base
|
|||
->param('execute', [], new Roles(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of role strings with execution permissions. By default no user is granted with any execute permissions. [learn more about roles](https://appwrite.io/docs/permissions#permission-roles). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 64 characters long.', true)
|
||||
->param('events', [], new ArrayList(new FunctionEvent(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Events list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' events are allowed.', true)
|
||||
->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('timeout', 15, new Range(1, (int) System::getEnv('_APP_FUNCTIONS_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)
|
||||
|
|
@ -103,6 +103,7 @@ class Update extends Base
|
|||
->inject('queueForBuilds')
|
||||
->inject('dbForPlatform')
|
||||
->inject('gitHub')
|
||||
->inject('executor')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +133,8 @@ class Update extends Base
|
|||
Event $queueForEvents,
|
||||
Build $queueForBuilds,
|
||||
Database $dbForPlatform,
|
||||
GitHub $github
|
||||
GitHub $github,
|
||||
Executor $executor
|
||||
) {
|
||||
// TODO: If only branch changes, re-deploy
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
|
@ -234,7 +236,6 @@ class Update extends Base
|
|||
|
||||
// Enforce Cold Start if spec limits change.
|
||||
if ($function->getAttribute('specification') !== $specification && !empty($function->getAttribute('deploymentId'))) {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
try {
|
||||
$executor->deleteRuntime($project->getId(), $function->getAttribute('deploymentId'));
|
||||
} catch (\Throwable $th) {
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ class XList extends Base
|
|||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/functions/runtimes')
|
||||
->groups(['api', 'functions'])
|
||||
->groups(['api'])
|
||||
->desc('List runtimes')
|
||||
->label('scope', 'functions.read')
|
||||
->label('scope', 'public')
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('sdk', new Method(
|
||||
namespace: 'functions',
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class XList extends Base
|
|||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/functions/templates')
|
||||
->desc('List templates')
|
||||
->groups(['api', 'functions'])
|
||||
->groups(['api'])
|
||||
->label('scope', 'public')
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('sdk', new Method(
|
||||
|
|
@ -71,10 +71,14 @@ class XList extends Base
|
|||
});
|
||||
}
|
||||
|
||||
$responseTemplates = \array_slice($templates, $offset, $limit);
|
||||
\usort($templates, function ($a, $b) {
|
||||
return $b['score'] <=> $a['score'];
|
||||
});
|
||||
|
||||
$templates = \array_slice($templates, $offset, $limit);
|
||||
$response->dynamic(new Document([
|
||||
'templates' => $responseTemplates,
|
||||
'total' => \count($responseTemplates),
|
||||
'templates' => $templates,
|
||||
'total' => \count($templates),
|
||||
]), Response::MODEL_TEMPLATE_FUNCTION_LIST);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -70,6 +72,7 @@ class Builds extends Action
|
|||
->inject('isResourceBlocked')
|
||||
->inject('deviceForFiles')
|
||||
->inject('log')
|
||||
->inject('executor')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -88,6 +91,7 @@ class Builds extends Action
|
|||
* @param Device $deviceForSites
|
||||
* @param Device $deviceForFiles
|
||||
* @param Log $log
|
||||
* @param Executor $executor
|
||||
* @return void
|
||||
* @throws \Utopia\Database\Exception
|
||||
*/
|
||||
|
|
@ -106,7 +110,8 @@ class Builds extends Action
|
|||
Device $deviceForSites,
|
||||
callable $isResourceBlocked,
|
||||
Device $deviceForFiles,
|
||||
Log $log
|
||||
Log $log,
|
||||
Executor $executor
|
||||
): void {
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
|
|
@ -144,7 +149,8 @@ class Builds extends Action
|
|||
$deployment,
|
||||
$template,
|
||||
$isResourceBlocked,
|
||||
$log
|
||||
$log,
|
||||
$executor
|
||||
);
|
||||
break;
|
||||
|
||||
|
|
@ -170,6 +176,7 @@ class Builds extends Action
|
|||
* @param Document $deployment
|
||||
* @param Document $template
|
||||
* @param Log $log
|
||||
* @param Executor $executor
|
||||
* @return void
|
||||
* @throws \Utopia\Database\Exception
|
||||
*
|
||||
|
|
@ -192,7 +199,8 @@ class Builds extends Action
|
|||
Document $deployment,
|
||||
Document $template,
|
||||
callable $isResourceBlocked,
|
||||
Log $log
|
||||
Log $log,
|
||||
Executor $executor
|
||||
): void {
|
||||
$resourceKey = match ($resource->getCollection()) {
|
||||
'functions' => 'functionId',
|
||||
|
|
@ -205,8 +213,6 @@ class Builds extends Action
|
|||
'functions' => $deviceForFunctions,
|
||||
};
|
||||
|
||||
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
|
||||
|
||||
$log->addTag($resourceKey, $resource->getId());
|
||||
|
||||
$resource = $dbForProject->getDocument($resource->getCollection(), $resource->getId());
|
||||
|
|
@ -559,6 +565,10 @@ class Builds extends Action
|
|||
// Some runtimes/frameworks can't compile with less memory than this
|
||||
$minMemory = $resource->getCollection() === 'sites' ? 2048 : 1024;
|
||||
|
||||
if ($resource->getAttribute('framework', '') === 'analog') {
|
||||
$minMemory = 4096;
|
||||
}
|
||||
|
||||
$cpus = $spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT;
|
||||
$memory = max($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT, $minMemory);
|
||||
$timeout = (int) System::getEnv('_APP_COMPUTE_BUILD_TIMEOUT', 900);
|
||||
|
|
@ -646,7 +656,11 @@ class Builds extends Action
|
|||
Co::join([
|
||||
Co\go(function () use ($executor, &$response, $project, $deployment, $source, $resource, $runtime, $vars, $command, $cpus, $memory, $timeout, &$err, $version) {
|
||||
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), "\'") . '"';
|
||||
if ($version === 'v2') {
|
||||
$command = 'tar -zxf /tmp/code.tar.gz -C /usr/code && cd /usr/local/src/ && ./build.sh';
|
||||
} else {
|
||||
$command = 'tar -zxf /tmp/code.tar.gz -C /mnt/code && helpers/build.sh ' . \trim(\escapeshellarg($command));
|
||||
}
|
||||
|
||||
$response = $executor->createRuntime(
|
||||
deploymentId: $deployment->getId(),
|
||||
|
|
@ -768,6 +782,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);
|
||||
}
|
||||
|
|
@ -779,7 +797,6 @@ 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));
|
||||
|
|
@ -788,25 +805,21 @@ class Builds extends Action
|
|||
foreach ($response['output'] as $log) {
|
||||
$logs .= $log['content'];
|
||||
}
|
||||
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
$date = \date('H:i:s');
|
||||
$logs .= "[90m[$date] [90m[[0mappwrite[90m][97m Screenshot capturing started. [0m\n";
|
||||
}
|
||||
|
||||
$deployment->setAttribute('buildLogs', $logs);
|
||||
|
||||
$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);
|
||||
}
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
$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");
|
||||
|
||||
/** Screenshot site */
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
try {
|
||||
$rule = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
|
||||
|
|
@ -844,33 +857,53 @@ 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, $apiKey, $resource, $client, &$screenshotError) {
|
||||
return function () use ($key, $configs, $apiKey, $resource, $client, &$screenshotError) {
|
||||
try {
|
||||
$config = $configs[$key];
|
||||
|
||||
$config['sleep'] = 3000;
|
||||
$config['headers'] = \array_merge($config['headers'] ?? [], [
|
||||
'x-appwrite-key' => API_KEY_DYNAMIC . '_' . $apiKey
|
||||
]);
|
||||
$config['sleep'] = 3000;
|
||||
|
||||
$frameworks = Config::getParam('frameworks', []);
|
||||
$framework = $frameworks[$resource->getAttribute('framework', '')] ?? null;
|
||||
if (!is_null($framework)) {
|
||||
$config['sleep'] = $framework['screenshotSleep'];
|
||||
}
|
||||
$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();
|
||||
|
||||
return ['key' => $key, 'screenshot' => $screenshot];
|
||||
} catch (\Throwable $th) {
|
||||
$screenshotError = $th->getMessage();
|
||||
return;
|
||||
}
|
||||
};
|
||||
}, \array_keys($configs)));
|
||||
|
||||
if (!\is_null($screenshotError)) {
|
||||
throw new \Exception($screenshotError);
|
||||
}
|
||||
|
||||
foreach ($screenshots as $data) {
|
||||
$key = $data['key'];
|
||||
$screenshot = $data['screenshot'];
|
||||
|
||||
$fileId = ID::unique();
|
||||
$fileName = $fileId . '.png';
|
||||
|
|
@ -907,12 +940,17 @@ class Builds extends Action
|
|||
'search' => implode(' ', [$fileId, $fileName]),
|
||||
'metadata' => ['content_type' => $deviceForFiles->getFileMimeType($path)],
|
||||
]);
|
||||
$file = Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file));
|
||||
|
||||
Authorization::skip(fn () => $dbForPlatform->createDocument('bucket_' . $bucket->getInternalId(), $file));
|
||||
|
||||
$deployment->setAttribute($key, $fileId);
|
||||
}
|
||||
|
||||
$dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
$logs = $deployment->getAttribute('buildLogs', '');
|
||||
$date = \date('H:i:s');
|
||||
$logs .= "[90m[$date] [90m[[0mappwrite[90m][97m Screenshot capturing finished. [0m\n";
|
||||
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
|
|
@ -921,9 +959,39 @@ class Builds extends Action
|
|||
Console::warning("Screenshot failed to generate:");
|
||||
Console::warning($th->getMessage());
|
||||
Console::warning($th->getTraceAsString());
|
||||
|
||||
$logs = $deployment->getAttribute('buildLogs', '');
|
||||
$date = \date('H:i:s');
|
||||
$logs .= "[90m[$date] [90m[[0mappwrite[90m][33m Screenshot capturing failed. Deployment will continue. [0m\n";
|
||||
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
|
||||
}
|
||||
}
|
||||
|
||||
$logs = $deployment->getAttribute('buildLogs', '');
|
||||
$date = \date('H:i:s');
|
||||
$logs .= "[90m[$date] [90m[[0mappwrite[90m][32m Deployment finished. [0m\n";
|
||||
$deployment->setAttribute('buildLogs', $logs);
|
||||
|
||||
/** 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);
|
||||
|
|
@ -1062,6 +1130,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;
|
||||
|
|
@ -1334,15 +1408,9 @@ class Builds extends Action
|
|||
default => throw new \Exception('Invalid resource type')
|
||||
};
|
||||
|
||||
$previweQrCode = match($resource->getCollection()) {
|
||||
'functions' => '',
|
||||
'sites' => 'https://cloud.appwrite.io/v1/avatars/qr?text=' . $previewUrl,
|
||||
default => throw new \Exception('Invalid resource type')
|
||||
};
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->parseComment($github->getComment($owner, $repositoryName, $commentId));
|
||||
$comment->addBuild($project, $resource, $resourceType, $status, $deployment->getId(), ['type' => 'logs'], $previewUrl, $previweQrCode);
|
||||
$comment->addBuild($project, $resource, $resourceType, $status, $deployment->getId(), ['type' => 'logs'], $previewUrl);
|
||||
$github->updateComment($owner, $repositoryName, $commentId, $comment->generateComment());
|
||||
} finally {
|
||||
$dbForPlatform->deleteDocument('vcsCommentLocks', $commentId);
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\API;
|
|||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
|
|
@ -19,7 +18,9 @@ use Utopia\Domains\Domain;
|
|||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
|
|
@ -95,13 +96,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
|
||||
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
|
||||
|
||||
|
|
@ -110,8 +104,23 @@ class Create extends Action
|
|||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($target->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Function;
|
|||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
|
|
@ -20,7 +19,9 @@ use Utopia\Domains\Domain;
|
|||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Create extends Action
|
||||
|
|
@ -96,13 +97,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
|
||||
|
|
@ -118,8 +112,23 @@ class Create extends Action
|
|||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($target->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Redirect;
|
|||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
|
|
@ -19,7 +18,9 @@ use Utopia\Domains\Domain;
|
|||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
|
|
@ -95,13 +96,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
|
||||
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
|
||||
|
||||
|
|
@ -110,8 +104,23 @@ class Create extends Action
|
|||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$dnsTarget = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($dnsTarget->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,11 @@ namespace Appwrite\Platform\Modules\Proxy\Http\Rules\Site;
|
|||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate;
|
||||
|
|
@ -20,7 +19,9 @@ use Utopia\Domains\Domain;
|
|||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\Domain as ValidatorDomain;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Create extends Action
|
||||
|
|
@ -96,13 +97,6 @@ class Create extends Action
|
|||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
|
||||
}
|
||||
|
||||
// Apex domain prevention due to CNAME limitations
|
||||
if (empty(App::getEnv('_APP_DOMAINS_NAMESERVERS', ''))) {
|
||||
if ($domain->get() === $domain->getRegisterable()) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'The instance does not allow root-level (apex) domains.');
|
||||
}
|
||||
}
|
||||
|
||||
$site = $dbForProject->getDocument('sites', $siteId);
|
||||
if ($site->isEmpty()) {
|
||||
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
|
||||
|
|
@ -118,8 +112,23 @@ class Create extends Action
|
|||
$status = 'verified';
|
||||
}
|
||||
if ($status === 'created') {
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validator = new CNAME($target->get());
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
if (empty($validators)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if ($validator->isValid($domain->get())) {
|
||||
$status = 'verifying';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,13 +241,15 @@ 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
|
||||
|
|
@ -306,6 +308,8 @@ 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,
|
||||
|
|
@ -314,7 +318,7 @@ class Create extends Action
|
|||
'search' => implode(' ', [$deploymentId]),
|
||||
'activate' => $activate,
|
||||
'sourceMetadata' => $metadata,
|
||||
'type' => $type
|
||||
'type' => $type,
|
||||
]));
|
||||
|
||||
$site = $site
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ class Create extends Action
|
|||
'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' => '',
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use Appwrite\SDK\Method;
|
|||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Executor\Executor;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
|
|
@ -56,6 +55,7 @@ class Update extends Action
|
|||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('executor')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,8 @@ class Update extends Action
|
|||
Response $response,
|
||||
Database $dbForProject,
|
||||
Document $project,
|
||||
Event $queueForEvents
|
||||
Event $queueForEvents,
|
||||
Executor $executor
|
||||
) {
|
||||
$site = $dbForProject->getDocument('sites', $siteId);
|
||||
|
||||
|
|
@ -99,7 +100,6 @@ class Update extends Action
|
|||
}
|
||||
|
||||
try {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
$executor->deleteRuntime($project->getId(), $deploymentId . "-build");
|
||||
} catch (\Throwable $th) {
|
||||
// Don't throw if the deployment doesn't exist
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class Create extends Base
|
|||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/sites/:siteId/deployments/template')
|
||||
->desc('Create deployment')
|
||||
->desc('Create template deployment')
|
||||
->groups(['api', 'sites'])
|
||||
->label('scope', 'sites.write')
|
||||
->label('resourceType', RESOURCE_TYPE_SITES)
|
||||
|
|
@ -156,6 +156,8 @@ class Create extends Base
|
|||
'resourceType' => 'sites',
|
||||
'buildCommands' => \implode(' && ', $commands),
|
||||
'buildOutput' => $site->getAttribute('outputDirectory', ''),
|
||||
'adapter' => $site->getAttribute('adapter', ''),
|
||||
'fallbackFile' => $site->getAttribute('fallbackFile', ''),
|
||||
'type' => 'manual',
|
||||
'search' => implode(' ', [$deploymentId]),
|
||||
'activate' => $activate,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class XList extends Base
|
|||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/sites/frameworks')
|
||||
->desc('List frameworks')
|
||||
->groups(['api', 'sites'])
|
||||
->label('scope', 'sites.read')
|
||||
->groups(['api'])
|
||||
->label('scope', 'public')
|
||||
->label('resourceType', RESOURCE_TYPE_SITES)
|
||||
->label('sdk', new Method(
|
||||
namespace: 'sites',
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ class Create extends Base
|
|||
->param('siteId', '', new CustomId(), 'Site ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', '', new Text(128), 'Site name. Max length: 128 chars.')
|
||||
->param('framework', '', new WhiteList(\array_keys(Config::getParam('frameworks')), true), 'Sites framework.')
|
||||
->param('enabled', true, new Boolean(), '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.', true) // TODO: Add logging param later
|
||||
->param('timeout', 15, new Range(1, (int) System::getEnv('_APP_COMPUTE_TIMEOUT', 900)), 'Maximum request time in seconds.', true)
|
||||
->param('enabled', true, new Boolean(), '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.', true)
|
||||
->param('logging', true, new Boolean(), 'When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.', true)
|
||||
->param('timeout', 30, new Range(1, (int) System::getEnv('_APP_SITES_TIMEOUT', 30)), 'Maximum request time in seconds.', true)
|
||||
->param('installCommand', '', new Text(8192, 0), 'Install Command.', true)
|
||||
->param('buildCommand', '', new Text(8192, 0), 'Build Command.', true)
|
||||
->param('outputDirectory', '', new Text(8192, 0), 'Output Directory for site.', true)
|
||||
|
|
@ -96,6 +97,7 @@ class Create extends Base
|
|||
string $name,
|
||||
string $framework,
|
||||
bool $enabled,
|
||||
bool $logging,
|
||||
int $timeout,
|
||||
string $installCommand,
|
||||
string $buildCommand,
|
||||
|
|
@ -140,6 +142,7 @@ class Create extends Base
|
|||
'$id' => $siteId,
|
||||
'enabled' => $enabled,
|
||||
'live' => true,
|
||||
'logging' => $logging,
|
||||
'name' => $name,
|
||||
'framework' => $framework,
|
||||
'deploymentInternalId' => '',
|
||||
|
|
|
|||
|
|
@ -68,8 +68,9 @@ class Update extends Base
|
|||
->param('siteId', '', new UID(), 'Site ID.')
|
||||
->param('name', '', new Text(128), 'Site name. Max length: 128 chars.')
|
||||
->param('framework', '', new WhiteList(\array_keys(Config::getParam('frameworks')), true), 'Sites framework.')
|
||||
->param('enabled', true, new Boolean(), '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.', true) // TODO: Add logging param later
|
||||
->param('timeout', 15, new Range(1, (int) System::getEnv('_APP_COMPUTE_TIMEOUT', 900)), 'Maximum request time in seconds.', true)
|
||||
->param('enabled', true, new Boolean(), '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.', true)
|
||||
->param('logging', true, new Boolean(), 'When disabled, request logs will exclude logs and errors, and site responses will be slightly faster.', true)
|
||||
->param('timeout', 30, new Range(1, (int) System::getEnv('_APP_SITES_TIMEOUT', 30)), 'Maximum request time in seconds.', true)
|
||||
->param('installCommand', '', new Text(8192, 0), 'Install Command.', true)
|
||||
->param('buildCommand', '', new Text(8192, 0), 'Build Command.', true)
|
||||
->param('outputDirectory', '', new Text(8192, 0), 'Output Directory for site.', true)
|
||||
|
|
@ -95,6 +96,7 @@ class Update extends Base
|
|||
->inject('queueForBuilds')
|
||||
->inject('dbForPlatform')
|
||||
->inject('gitHub')
|
||||
->inject('executor')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
|
|
@ -103,6 +105,7 @@ class Update extends Base
|
|||
string $name,
|
||||
string $framework,
|
||||
bool $enabled,
|
||||
bool $logging,
|
||||
int $timeout,
|
||||
string $installCommand,
|
||||
string $buildCommand,
|
||||
|
|
@ -123,7 +126,8 @@ class Update extends Base
|
|||
Event $queueForEvents,
|
||||
Build $queueForBuilds,
|
||||
Database $dbForPlatform,
|
||||
GitHub $github
|
||||
GitHub $github,
|
||||
Executor $executor
|
||||
) {
|
||||
if (!empty($adapter)) {
|
||||
$configFramework = Config::getParam('frameworks')[$framework] ?? [];
|
||||
|
|
@ -231,7 +235,6 @@ class Update extends Base
|
|||
|
||||
// Enforce Cold Start if spec limits change.
|
||||
if ($site->getAttribute('specification') !== $specification && !empty($site->getAttribute('deploymentId'))) {
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
try {
|
||||
$executor->deleteRuntime($project->getId(), $site->getAttribute('deploymentId'));
|
||||
} catch (\Throwable $th) {
|
||||
|
|
@ -246,6 +249,7 @@ class Update extends Base
|
|||
'name' => $name,
|
||||
'framework' => $framework,
|
||||
'enabled' => $enabled,
|
||||
'logging' => $logging,
|
||||
'live' => $live,
|
||||
'timeout' => $timeout,
|
||||
'installCommand' => $installCommand,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Get extends Base
|
|||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/sites/templates/:templateId')
|
||||
->desc('Get site template')
|
||||
->groups(['api', 'sites'])
|
||||
->groups(['api'])
|
||||
->label('scope', 'public')
|
||||
->label('resourceType', RESOURCE_TYPE_SITES)
|
||||
->label('sdk', new Method(
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class XList extends Base
|
|||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/sites/templates')
|
||||
->desc('List templates')
|
||||
->groups(['api', 'sites'])
|
||||
->groups(['api'])
|
||||
->label('scope', 'public')
|
||||
->label('resourceType', RESOURCE_TYPE_SITES)
|
||||
->label('sdk', new Method(
|
||||
|
|
@ -76,10 +76,15 @@ class XList extends Base
|
|||
});
|
||||
}
|
||||
|
||||
$responseTemplates = \array_slice($templates, $offset, $limit);
|
||||
\usort($templates, function ($a, $b) {
|
||||
return $b['score'] <=> $a['score'];
|
||||
});
|
||||
|
||||
$templates = \array_slice($templates, $offset, $limit);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'templates' => $responseTemplates,
|
||||
'total' => \count($responseTemplates),
|
||||
'templates' => $templates,
|
||||
'total' => \count($templates),
|
||||
]), Response::MODEL_TEMPLATE_SITE_LIST);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use Utopia\Registry\Registry;
|
|||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Doctor extends Action
|
||||
{
|
||||
|
|
@ -43,19 +44,31 @@ class Doctor extends Action
|
|||
Console::log('[Settings]');
|
||||
|
||||
$domain = new Domain(System::getEnv('_APP_DOMAIN'));
|
||||
|
||||
if (!$domain->isKnown() || $domain->isTest()) {
|
||||
Console::log('🔴 Hostname has no public suffix (' . $domain->get() . ')');
|
||||
Console::log('🔴 Hostname is not valid (' . $domain->get() . ')');
|
||||
} else {
|
||||
Console::log('🟢 Hostname has a public suffix (' . $domain->get() . ')');
|
||||
Console::log('🟢 Hostname is valid (' . $domain->get() . ')');
|
||||
}
|
||||
|
||||
$domain = new Domain(System::getEnv('_APP_DOMAIN_TARGET'));
|
||||
|
||||
$domain = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
|
||||
if (!$domain->isKnown() || $domain->isTest()) {
|
||||
Console::log('🔴 CNAME target has no public suffix (' . $domain->get() . ')');
|
||||
Console::log('🔴 CNAME record target is not valid (' . $domain->get() . ')');
|
||||
} else {
|
||||
Console::log('🟢 CNAME target has a public suffix (' . $domain->get() . ')');
|
||||
Console::log('🟢 CNAME record target is valid (' . $domain->get() . ')');
|
||||
}
|
||||
|
||||
$ipv4 = new IP(IP::V4);
|
||||
if (!$ipv4->isValid(System::getEnv('_APP_DOMAIN_TARGET_A'))) {
|
||||
Console::log('🔴 A record target is not valid (' . System::getEnv('_APP_DOMAIN_TARGET_A') . ')');
|
||||
} else {
|
||||
Console::log('🟢 A record target is valid (' . System::getEnv('_APP_DOMAIN_TARGET_A') . ')');
|
||||
}
|
||||
|
||||
$ipv6 = new IP(IP::V6);
|
||||
if (!$ipv6->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA'))) {
|
||||
Console::log('🔴 AAAA record target is not valid (' . System::getEnv('_APP_DOMAIN_TARGET_AAAA') . ')');
|
||||
} else {
|
||||
Console::log('🟢 AAAA record target is valid (' . System::getEnv('_APP_DOMAIN_TARGET_AAAA') . ')');
|
||||
}
|
||||
|
||||
if (System::getEnv('_APP_OPENSSL_KEY_V1') === 'your-secret-key' || empty(System::getEnv('_APP_OPENSSL_KEY_V1'))) {
|
||||
|
|
|
|||
|
|
@ -103,8 +103,15 @@ abstract class ScheduleBase extends Action
|
|||
$paginationQueries[] = Query::cursorAfter($latestDocument);
|
||||
}
|
||||
|
||||
// Temporarly accepting both 'fra' and 'default'
|
||||
// When all migrated, only use _APP_REGION with 'default' as default value
|
||||
$regions = [System::getEnv('_APP_REGION', 'default')];
|
||||
if (!in_array('default', $regions)) {
|
||||
$regions[] = 'default';
|
||||
}
|
||||
|
||||
$results = $dbForPlatform->find('schedules', \array_merge($paginationQueries, [
|
||||
Query::equal('region', [System::getEnv('_APP_REGION', 'default')]),
|
||||
Query::equal('region', $regions),
|
||||
Query::equal('resourceType', [static::getSupportedResource()]),
|
||||
Query::equal('active', [true]),
|
||||
]));
|
||||
|
|
@ -153,8 +160,15 @@ abstract class ScheduleBase extends Action
|
|||
$paginationQueries[] = Query::cursorAfter($latestDocument);
|
||||
}
|
||||
|
||||
// Temporarly accepting both 'fra' and 'default'
|
||||
// When all migrated, only use _APP_REGION with 'default' as default value
|
||||
$regions = [System::getEnv('_APP_REGION', 'default')];
|
||||
if (!in_array('default', $regions)) {
|
||||
$regions[] = 'default';
|
||||
}
|
||||
|
||||
$results = $dbForPlatform->find('schedules', \array_merge($paginationQueries, [
|
||||
Query::equal('region', [System::getEnv('_APP_REGION', 'default')]),
|
||||
Query::equal('region', $regions),
|
||||
Query::equal('resourceType', [static::getSupportedResource()]),
|
||||
Query::greaterThanEqual('resourceUpdatedAt', $lastSyncUpdate),
|
||||
]));
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ class Screenshot extends Action
|
|||
'installCommand' => $framework['installCommand'] ?? '',
|
||||
'outputDirectory' => $framework['outputDirectory'] ?? '',
|
||||
'providerRootDirectory' => $framework['providerRootDirectory'],
|
||||
'timeout' => 60
|
||||
'timeout' => 30
|
||||
]);
|
||||
|
||||
if ($site['headers']['status-code'] !== 201) {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,11 @@ class Audits extends Action
|
|||
Console::info('Aggregating audit logs');
|
||||
|
||||
$event = $payload['event'] ?? '';
|
||||
$auditPayload = $payload['payload'] ?? '';
|
||||
|
||||
$auditPayload = '';
|
||||
if ($project->getId() === 'console') {
|
||||
$auditPayload = $payload['payload'] ?? '';
|
||||
}
|
||||
$mode = $payload['mode'] ?? '';
|
||||
$resource = $payload['resource'] ?? '';
|
||||
$userAgent = $payload['userAgent'] ?? '';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use Appwrite\Event\Func;
|
|||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\DNS;
|
||||
use Appwrite\Template\Template;
|
||||
use Appwrite\Utopia\Response\Model\Rule;
|
||||
use Exception;
|
||||
|
|
@ -28,6 +28,8 @@ use Utopia\Logger\Log;
|
|||
use Utopia\Platform\Action;
|
||||
use Utopia\Queue\Message;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\AnyOf;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Certificates extends Action
|
||||
{
|
||||
|
|
@ -290,22 +292,39 @@ class Certificates extends Action
|
|||
}
|
||||
|
||||
if (!$isMainDomain) {
|
||||
// TODO: Would be awesome to also support A/AAAA records here. Maybe dry run?
|
||||
// Validate if domain target is properly configured
|
||||
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
|
||||
$validationStart = \microtime(true);
|
||||
|
||||
if (!$target->isKnown() || $target->isTest()) {
|
||||
throw new Exception('Unreachable CNAME target (' . $target->get() . '), please use a domain with a public suffix.');
|
||||
$validators = [];
|
||||
$targetCNAME = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME', ''));
|
||||
if (!$targetCNAME->isKnown() || $targetCNAME->isTest()) {
|
||||
$validators[] = new DNS($targetCNAME->get(), DNS::RECORD_CNAME);
|
||||
}
|
||||
if ((new IP(IP::V4))->isValid(System::getEnv('_APP_DOMAIN_TARGET_A', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_A', ''), DNS::RECORD_A);
|
||||
}
|
||||
if ((new IP(IP::V6))->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''))) {
|
||||
$validators[] = new DNS(System::getEnv('_APP_DOMAIN_TARGET_AAAA', ''), DNS::RECORD_AAAA);
|
||||
}
|
||||
|
||||
// Validate if domain target is properly configured
|
||||
if (empty($validators)) {
|
||||
throw new Exception('At least one of domain targets environment variable must be configured.');
|
||||
}
|
||||
|
||||
// Verify domain with DNS records
|
||||
$validationStart = \microtime(true);
|
||||
$validator = new CNAME($target->get());
|
||||
$validator = new AnyOf($validators, AnyOf::TYPE_STRING);
|
||||
if (!$validator->isValid($domain->get())) {
|
||||
$log->addExtra('dnsTiming', \strval(\microtime(true) - $validationStart));
|
||||
$log->addTag('dnsDomain', $domain->get());
|
||||
|
||||
$error = $validator->getLogs();
|
||||
$errors = [];
|
||||
foreach ($validators as $validator) {
|
||||
if (!empty($validator->getLogs())) {
|
||||
$errors[] = $validator->getLogs();
|
||||
}
|
||||
}
|
||||
|
||||
$error = \implode("\n", $errors);
|
||||
$log->addExtra('dnsResponse', \is_array($error) ? \json_encode($error) : \strval($error));
|
||||
|
||||
throw new Exception('Failed to verify domain DNS records.');
|
||||
|
|
|
|||
|
|
@ -572,7 +572,8 @@ class Databases extends Action
|
|||
try {
|
||||
$documents = $database->deleteDocuments($collectionId, $queries);
|
||||
} catch (\Throwable $th) {
|
||||
Console::error('Failed to delete documents for collection ' . $collectionId . ': ' . $th->getMessage());
|
||||
$tenant = $database->getSharedTables() ? 'Tenant:'.$database->getTenant() : '';
|
||||
Console::error("Failed to delete documents for collection:{$database->getNamespace()}_{$collectionId} {$tenant} :{$th->getMessage()}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ use Utopia\System\System;
|
|||
|
||||
class Deletes extends Action
|
||||
{
|
||||
protected array $selects = ['$internalId', '$id', '$collection', '$permissions', '$updatedAt'];
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'deletes';
|
||||
|
|
@ -55,6 +57,7 @@ class Deletes extends Action
|
|||
->inject('deviceForBuilds')
|
||||
->inject('deviceForCache')
|
||||
->inject('certificates')
|
||||
->inject('executor')
|
||||
->inject('executionRetention')
|
||||
->inject('auditRetention')
|
||||
->inject('log')
|
||||
|
|
@ -77,6 +80,7 @@ class Deletes extends Action
|
|||
Device $deviceForBuilds,
|
||||
Device $deviceForCache,
|
||||
CertificatesAdapter $certificates,
|
||||
Executor $executor,
|
||||
string $executionRetention,
|
||||
string $auditRetention,
|
||||
Log $log
|
||||
|
|
@ -107,10 +111,10 @@ class Deletes extends Action
|
|||
$this->deleteSite($dbForPlatform, $getProjectDB, $deviceForSites, $deviceForBuilds, $deviceForFiles, $document, $certificates, $project);
|
||||
break;
|
||||
case DELETE_TYPE_FUNCTIONS:
|
||||
$this->deleteFunction($dbForPlatform, $getProjectDB, $deviceForFunctions, $deviceForBuilds, $certificates, $document, $project);
|
||||
$this->deleteFunction($dbForPlatform, $getProjectDB, $deviceForFunctions, $deviceForBuilds, $certificates, $document, $project, $executor);
|
||||
break;
|
||||
case DELETE_TYPE_DEPLOYMENTS:
|
||||
$this->deleteDeployment($dbForPlatform, $getProjectDB, $deviceForFunctions, $deviceForSites, $deviceForBuilds, $deviceForFiles, $document, $certificates, $project);
|
||||
$this->deleteDeployment($dbForPlatform, $getProjectDB, $deviceForFunctions, $deviceForSites, $deviceForBuilds, $deviceForFiles, $document, $certificates, $project, $executor);
|
||||
break;
|
||||
case DELETE_TYPE_USERS:
|
||||
$this->deleteUser($getProjectDB, $document, $project);
|
||||
|
|
@ -196,10 +200,17 @@ class Deletes extends Action
|
|||
*/
|
||||
private function deleteSchedules(Database $dbForPlatform, callable $getProjectDB, string $datetime): void
|
||||
{
|
||||
// Temporarly accepting both 'fra' and 'default'
|
||||
// When all migrated, only use _APP_REGION with 'default' as default value
|
||||
$regions = [System::getEnv('_APP_REGION', 'default')];
|
||||
if (!in_array('default', $regions)) {
|
||||
$regions[] = 'default';
|
||||
}
|
||||
|
||||
$this->listByGroup(
|
||||
'schedules',
|
||||
[
|
||||
Query::equal('region', [System::getEnv('_APP_REGION', 'default')]),
|
||||
Query::equal('region', $regions),
|
||||
Query::lessThanEqual('resourceUpdatedAt', $datetime),
|
||||
Query::equal('active', [false]),
|
||||
],
|
||||
|
|
@ -264,7 +275,8 @@ class Deletes extends Action
|
|||
$this->deleteByGroup(
|
||||
'subscribers',
|
||||
[
|
||||
Query::equal('topicInternalId', [$topic->getInternalId()])
|
||||
Query::equal('topicInternalId', [$topic->getInternalId()]),
|
||||
Query::orderAsc(),
|
||||
],
|
||||
$getProjectDB($project)
|
||||
);
|
||||
|
|
@ -285,7 +297,8 @@ class Deletes extends Action
|
|||
$this->deleteByGroup(
|
||||
'subscribers',
|
||||
[
|
||||
Query::equal('targetInternalId', [$target->getInternalId()])
|
||||
Query::equal('targetInternalId', [$target->getInternalId()]),
|
||||
Query::orderAsc(),
|
||||
],
|
||||
$dbForProject,
|
||||
function (Document $subscriber) use ($dbForProject, $target) {
|
||||
|
|
@ -322,7 +335,8 @@ class Deletes extends Action
|
|||
$this->deleteByGroup(
|
||||
'targets',
|
||||
[
|
||||
Query::equal('expired', [true])
|
||||
Query::equal('expired', [true]),
|
||||
Query::orderAsc(),
|
||||
],
|
||||
$getProjectDB($project),
|
||||
function (Document $target) use ($getProjectDB, $project) {
|
||||
|
|
@ -336,7 +350,8 @@ class Deletes extends Action
|
|||
$this->deleteByGroup(
|
||||
'targets',
|
||||
[
|
||||
Query::equal('sessionInternalId', [$session->getInternalId()])
|
||||
Query::equal('sessionInternalId', [$session->getInternalId()]),
|
||||
Query::orderAsc(),
|
||||
],
|
||||
$getProjectDB($project),
|
||||
function (Document $target) use ($getProjectDB, $project) {
|
||||
|
|
@ -363,14 +378,20 @@ class Deletes extends Action
|
|||
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId)
|
||||
);
|
||||
|
||||
$query[] = Query::equal('resource', [$resource]);
|
||||
$queries = [
|
||||
Query::equal('resource', [$resource])
|
||||
];
|
||||
|
||||
if (!empty($resourceType)) {
|
||||
$query[] = Query::equal('resourceType', [$resourceType]);
|
||||
$queries[] = Query::equal('resourceType', [$resourceType]);
|
||||
}
|
||||
|
||||
$queries[] = Query::select($this->selects);
|
||||
$queries[] = Query::orderAsc();
|
||||
|
||||
$this->deleteByGroup(
|
||||
'cache',
|
||||
$query,
|
||||
$queries,
|
||||
$dbForProject,
|
||||
function (Document $document) use ($cache, $projectId) {
|
||||
$path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId();
|
||||
|
|
@ -401,15 +422,16 @@ class Deletes extends Action
|
|||
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId)
|
||||
);
|
||||
|
||||
$query = [
|
||||
$queries = [
|
||||
Query::select([...$this->selects, 'accessedAt']),
|
||||
Query::lessThan('accessedAt', $datetime),
|
||||
Query::orderDesc('accessedAt'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::orderDesc(),
|
||||
];
|
||||
|
||||
$this->deleteByGroup(
|
||||
'cache',
|
||||
$query,
|
||||
$queries,
|
||||
$dbForProject,
|
||||
function (Document $document) use ($cache, $projectId) {
|
||||
$path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId();
|
||||
|
|
@ -435,12 +457,15 @@ class Deletes extends Action
|
|||
/** @var Database $dbForProject*/
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$selects = [...$this->selects, 'time'];
|
||||
|
||||
// Delete Usage stats from projectDB
|
||||
$this->deleteByGroup('stats', [
|
||||
Query::select($selects),
|
||||
Query::equal('period', ['1h']),
|
||||
Query::lessThan('time', $hourlyUsageRetentionDatetime),
|
||||
Query::orderDesc('time'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::equal('period', ['1h']),
|
||||
Query::orderDesc(),
|
||||
], $dbForProject);
|
||||
|
||||
if ($project->getId() !== 'console') {
|
||||
|
|
@ -449,10 +474,11 @@ class Deletes extends Action
|
|||
|
||||
// Delete Usage stats from logsDB
|
||||
$this->deleteByGroup('stats', [
|
||||
Query::select($selects),
|
||||
Query::equal('period', ['1h']),
|
||||
Query::lessThan('time', $hourlyUsageRetentionDatetime),
|
||||
Query::orderDesc('time'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::equal('period', ['1h']),
|
||||
Query::orderDesc(),
|
||||
], $dbForLogs);
|
||||
}
|
||||
}
|
||||
|
|
@ -473,7 +499,8 @@ class Deletes extends Action
|
|||
$this->deleteByGroup(
|
||||
'memberships',
|
||||
[
|
||||
Query::equal('teamInternalId', [$teamInternalId])
|
||||
Query::equal('teamInternalId', [$teamInternalId]),
|
||||
Query::orderAsc()
|
||||
],
|
||||
$dbForProject,
|
||||
function (Document $membership) use ($dbForProject) {
|
||||
|
|
@ -564,7 +591,13 @@ class Deletes extends Action
|
|||
if ($projectTables || !\in_array($collection->getId(), $projectCollectionIds)) {
|
||||
$dbForProject->deleteCollection($collection->getId());
|
||||
} else {
|
||||
$this->deleteByGroup($collection->getId(), [], database: $dbForProject);
|
||||
$this->deleteByGroup(
|
||||
$collection->getId(),
|
||||
[
|
||||
Query::orderAsc()
|
||||
],
|
||||
database: $dbForProject
|
||||
);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
Console::error('Error deleting '.$collection->getId().' '.$e->getMessage());
|
||||
|
|
@ -584,58 +617,78 @@ class Deletes extends Action
|
|||
|
||||
// Delete Platforms
|
||||
$this->deleteByGroup('platforms', [
|
||||
Query::equal('projectInternalId', [$projectInternalId])
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete project and function rules
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('projectInternalId', [$projectInternalId])
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
|
||||
// Delete Keys
|
||||
$this->deleteByGroup('keys', [
|
||||
Query::equal('projectInternalId', [$projectInternalId])
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete Webhooks
|
||||
$this->deleteByGroup('webhooks', [
|
||||
Query::equal('projectInternalId', [$projectInternalId])
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete VCS Installations
|
||||
$this->deleteByGroup('installations', [
|
||||
Query::equal('projectInternalId', [$projectInternalId])
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete VCS Repositories
|
||||
$this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete VCS comments
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete Schedules (No projectInternalId in this collection)
|
||||
// Delete Schedules
|
||||
$this->deleteByGroup('schedules', [
|
||||
Query::equal('projectId', [$projectId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete metadata table
|
||||
if ($projectTables) {
|
||||
$dbForProject->deleteCollection(Database::METADATA);
|
||||
} elseif ($sharedTablesV1) {
|
||||
$this->deleteByGroup(Database::METADATA, [], $dbForProject);
|
||||
$this->deleteByGroup(
|
||||
Database::METADATA,
|
||||
[
|
||||
Query::orderAsc()
|
||||
],
|
||||
$dbForProject
|
||||
);
|
||||
} elseif ($sharedTablesV2) {
|
||||
$queries = \array_map(
|
||||
fn ($id) => Query::notEqual('$id', $id),
|
||||
$projectCollectionIds
|
||||
);
|
||||
|
||||
$this->deleteByGroup(Database::METADATA, $queries, $dbForProject);
|
||||
$queries[] = Query::orderAsc();
|
||||
|
||||
$this->deleteByGroup(
|
||||
Database::METADATA,
|
||||
$queries,
|
||||
$dbForProject
|
||||
);
|
||||
}
|
||||
|
||||
// Delete all storage directories
|
||||
|
|
@ -661,14 +714,16 @@ class Deletes extends Action
|
|||
|
||||
// Delete all sessions of this user from the sessions table and update the sessions field of the user record
|
||||
$this->deleteByGroup('sessions', [
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $userId);
|
||||
|
||||
// Delete Memberships and decrement team membership counts
|
||||
$this->deleteByGroup('memberships', [
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($dbForProject) {
|
||||
if ($document->getAttribute('confirm')) { // Count only confirmed members
|
||||
$teamId = $document->getAttribute('teamId');
|
||||
|
|
@ -681,19 +736,22 @@ class Deletes extends Action
|
|||
|
||||
// Delete tokens
|
||||
$this->deleteByGroup('tokens', [
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
// Delete identities
|
||||
$this->deleteByGroup('identities', [
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
// Delete targets
|
||||
$this->deleteByGroup(
|
||||
'targets',
|
||||
[
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
],
|
||||
$dbForProject,
|
||||
function (Document $target) use ($getProjectDB, $project) {
|
||||
|
|
@ -715,9 +773,10 @@ class Deletes extends Action
|
|||
|
||||
// Delete Executions
|
||||
$this->deleteByGroup('executions', [
|
||||
Query::select([...$this->selects, '$createdAt']),
|
||||
Query::lessThan('$createdAt', $datetime),
|
||||
Query::orderDesc('$createdAt'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::orderDesc(),
|
||||
], $dbForProject);
|
||||
}
|
||||
|
||||
|
|
@ -735,9 +794,10 @@ class Deletes extends Action
|
|||
|
||||
// Delete Sessions
|
||||
$this->deleteByGroup('sessions', [
|
||||
Query::select([...$this->selects, '$createdAt']),
|
||||
Query::lessThan('$createdAt', $expired),
|
||||
Query::orderDesc('$createdAt'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::orderDesc(),
|
||||
], $dbForProject);
|
||||
}
|
||||
|
||||
|
|
@ -753,14 +813,14 @@ class Deletes extends Action
|
|||
$this->deleteByGroup('realtime', [
|
||||
Query::lessThan('timestamp', $datetime),
|
||||
Query::orderDesc('timestamp'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::orderAsc(),
|
||||
], $dbForPlatform);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Database $dbForPlatform
|
||||
* @param callable $getProjectDB
|
||||
* @param string $datetime
|
||||
* @param string $auditRetention
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
|
|
@ -771,9 +831,10 @@ class Deletes extends Action
|
|||
|
||||
try {
|
||||
$this->deleteByGroup(Audit::COLLECTION, [
|
||||
Query::select([...$this->selects, 'time']),
|
||||
Query::lessThan('time', $auditRetention),
|
||||
Query::orderDesc('time'),
|
||||
Query::orderDesc('$internalId'),
|
||||
Query::orderAsc(),
|
||||
], $dbForProject);
|
||||
} catch (DatabaseException $e) {
|
||||
Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $e->getMessage());
|
||||
|
|
@ -831,35 +892,8 @@ class Deletes extends Action
|
|||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
$this->deleteDeploymentFiles($deviceForSites, $document);
|
||||
$this->deleteDeploymentScreenshots($deviceForFiles, $dbForPlatform, $document);
|
||||
$this->deleteDeploymentRules($dbForPlatform, $document, $project, $certificates);
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete builds
|
||||
*/
|
||||
Console::info("Deleting builds for site " . $siteId);
|
||||
foreach ($deploymentInternalIds as $deploymentInternalId) {
|
||||
$this->deleteByGroup('builds', [
|
||||
Query::equal('deploymentInternalId', [$deploymentInternalId])
|
||||
], $dbForProject, function (Document $document) use ($deviceForBuilds) {
|
||||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete rules for all deployments of the site
|
||||
*/
|
||||
foreach ($deploymentIds as $deploymentId) {
|
||||
Console::info("Deleting rules for site " . $siteId . "'s deployment " . $deploymentId);
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('type', ['deployment']),
|
||||
Query::equal('value', [$deploymentId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()])
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete VCS Repositories and VCS Comments
|
||||
*/
|
||||
|
|
@ -884,10 +918,11 @@ class Deletes extends Action
|
|||
* @param Device $deviceForBuilds
|
||||
* @param Document $document function document
|
||||
* @param Document $project
|
||||
* @param Executor $executor
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteFunction(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFunctions, Device $deviceForBuilds, CertificatesAdapter $certificates, Document $document, Document $project): void
|
||||
private function deleteFunction(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFunctions, Device $deviceForBuilds, CertificatesAdapter $certificates, Document $document, Document $project, Executor $executor): void
|
||||
{
|
||||
$projectId = $project->getId();
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
|
@ -900,9 +935,10 @@ class Deletes extends Action
|
|||
Console::info("Deleting rules for function " . $functionId);
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('type', ['deployment']),
|
||||
Query::equal('deploymentResourceType', ['site']),
|
||||
Query::equal('deploymentResourceType', ['function']),
|
||||
Query::equal('deploymentResourceInternalId', [$functionInternalId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()])
|
||||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($project, $dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
|
|
@ -912,8 +948,9 @@ class Deletes extends Action
|
|||
*/
|
||||
Console::info("Deleting variables for function " . $functionId);
|
||||
$this->deleteByGroup('variables', [
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::equal('resourceInternalId', [$functionInternalId])
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
|
|
@ -923,12 +960,12 @@ class Deletes extends Action
|
|||
|
||||
$deploymentInternalIds = [];
|
||||
$this->deleteByGroup('deployments', [
|
||||
Query::equal('resourceInternalId', [$functionInternalId])
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($dbForPlatform, $project, $certificates, $deviceForFunctions, $deviceForBuilds, &$deploymentInternalIds) {
|
||||
$deploymentInternalIds[] = $document->getInternalId();
|
||||
$this->deleteDeploymentFiles($deviceForFunctions, $document);
|
||||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
$this->deleteDeploymentRules($dbForPlatform, $document, $project, $certificates);
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -936,7 +973,9 @@ class Deletes extends Action
|
|||
*/
|
||||
Console::info("Deleting executions for function " . $functionId);
|
||||
$this->deleteByGroup('executions', [
|
||||
Query::equal('functionInternalId', [$functionInternalId])
|
||||
Query::select($this->selects),
|
||||
Query::equal('functionInternalId', [$functionInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
|
|
@ -947,12 +986,15 @@ class Deletes extends Action
|
|||
Query::equal('projectInternalId', [$project->getInternalId()]),
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform) {
|
||||
$providerRepositoryId = $document->getAttribute('providerRepositoryId', '');
|
||||
$projectInternalId = $document->getAttribute('projectInternalId', '');
|
||||
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
});
|
||||
|
||||
|
|
@ -960,19 +1002,7 @@ class Deletes extends Action
|
|||
* Request executor to delete all deployment containers
|
||||
*/
|
||||
Console::info("Requesting executor to delete all deployment containers for function " . $functionId);
|
||||
$this->deleteRuntimes($getProjectDB, $document, $project);
|
||||
}
|
||||
|
||||
private function deleteDeploymentRules(Database $dbForPlatform, Document $deployment, Document $project, CertificatesAdapter $certificates): void
|
||||
{
|
||||
Console::info("Deleting rules for site " . $deployment->getId());
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('type', ['deployment']),
|
||||
Query::equal('deploymentInternalId', [$deployment->getInternalId()]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()])
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
$this->deleteRuntimes($getProjectDB, $document, $project, $executor);
|
||||
}
|
||||
|
||||
private function deleteDeploymentScreenshots(Device $deviceForFiles, Database $dbForPlatform, Document $deployment): void
|
||||
|
|
@ -1091,10 +1121,11 @@ class Deletes extends Action
|
|||
* @param Device $deviceForBuilds
|
||||
* @param Document $document
|
||||
* @param Document $project
|
||||
* @param Executor $executor
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteDeployment(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFunctions, Device $deviceForSites, Device $deviceForBuilds, Device $deviceForFiles, Document $document, CertificatesAdapter $certificates, Document $project): void
|
||||
private function deleteDeployment(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFunctions, Device $deviceForSites, Device $deviceForBuilds, Device $deviceForFiles, Document $document, CertificatesAdapter $certificates, Document $project, Executor $executor): void
|
||||
{
|
||||
$projectId = $project->getId();
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
|
@ -1125,9 +1156,9 @@ class Deletes extends Action
|
|||
*/
|
||||
Console::info("Deleting rules for deployment " . $deploymentId);
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('trigger', ['manual']),
|
||||
Query::equal('trigger', ['deployment']),
|
||||
Query::equal('type', ['deployment']),
|
||||
Query::equal('deploymentResourceInternalId', [$deploymentInternalId]),
|
||||
Query::equal('deploymentInternalId', [$deploymentInternalId]),
|
||||
Query::equal('projectInternalId', [$project->getInternalId()])
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
|
|
@ -1137,7 +1168,7 @@ class Deletes extends Action
|
|||
* Request executor to delete all deployment containers
|
||||
*/
|
||||
Console::info("Requesting executor to delete deployment container for deployment " . $deploymentId);
|
||||
$this->deleteRuntimes($getProjectDB, $document, $project);
|
||||
$this->deleteRuntimes($getProjectDB, $document, $project, $executor);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1156,10 +1187,15 @@ class Deletes extends Action
|
|||
): void {
|
||||
$start = \microtime(true);
|
||||
|
||||
/**
|
||||
* deleteDocuments uses a cursor, we need to add a unique order by field or use default
|
||||
*/
|
||||
|
||||
try {
|
||||
$documents = $database->deleteDocuments($collection, $queries);
|
||||
} catch (Throwable $th) {
|
||||
Console::error('Failed to delete documents for collection ' . $collection . ': ' . $th->getMessage());
|
||||
$tenant = $database->getSharedTables() ? 'Tenant:'.$database->getTenant() : '';
|
||||
Console::error("Failed to delete documents for collection:{$database->getNamespace()}_{$collection} {$tenant} :{$th->getMessage()}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1288,13 +1324,12 @@ class Deletes extends Action
|
|||
* @param callable $getProjectDB
|
||||
* @param ?Document $function
|
||||
* @param Document $project
|
||||
* @param Executor $executor
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteRuntimes(callable $getProjectDB, ?Document $function, Document $project): void
|
||||
private function deleteRuntimes(callable $getProjectDB, ?Document $function, Document $project, Executor $executor): void
|
||||
{
|
||||
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
|
||||
|
||||
$deleteByFunction = function (Document $function) use ($getProjectDB, $project, $executor) {
|
||||
$this->listByGroup(
|
||||
'deployments',
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ class Functions extends Action
|
|||
->inject('queueForEvents')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('log')
|
||||
->inject('executor')
|
||||
->inject('isResourceBlocked')
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
|
@ -65,6 +66,7 @@ class Functions extends Action
|
|||
Event $queueForEvents,
|
||||
StatsUsage $queueForStatsUsage,
|
||||
Log $log,
|
||||
Executor $executor,
|
||||
callable $isResourceBlocked
|
||||
): void {
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
|
@ -156,6 +158,7 @@ class Functions extends Action
|
|||
queueForEvents: $queueForEvents,
|
||||
project: $project,
|
||||
function: $function,
|
||||
executor: $executor,
|
||||
trigger: 'event',
|
||||
path: '/',
|
||||
method: 'POST',
|
||||
|
|
@ -198,6 +201,7 @@ class Functions extends Action
|
|||
queueForEvents: $queueForEvents,
|
||||
project: $project,
|
||||
function: $function,
|
||||
executor: $executor,
|
||||
trigger: 'http',
|
||||
path: $path,
|
||||
method: $method,
|
||||
|
|
@ -222,6 +226,7 @@ class Functions extends Action
|
|||
queueForEvents: $queueForEvents,
|
||||
project: $project,
|
||||
function: $function,
|
||||
executor: $executor,
|
||||
trigger: 'schedule',
|
||||
path: $path,
|
||||
method: $method,
|
||||
|
|
@ -308,6 +313,7 @@ class Functions extends Action
|
|||
* @param Event $queueForEvents
|
||||
* @param Document $project
|
||||
* @param Document $function
|
||||
* @param Executor $executor
|
||||
* @param string $trigger
|
||||
* @param string $path
|
||||
* @param string $method
|
||||
|
|
@ -334,6 +340,7 @@ class Functions extends Action
|
|||
Event $queueForEvents,
|
||||
Document $project,
|
||||
Document $function,
|
||||
Executor $executor,
|
||||
string $trigger,
|
||||
string $path,
|
||||
string $method,
|
||||
|
|
@ -512,7 +519,6 @@ class Functions extends Action
|
|||
try {
|
||||
$version = $function->getAttribute('version', 'v2');
|
||||
$command = $runtime['startCommand'];
|
||||
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
|
||||
$command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"';
|
||||
$executionResponse = $executor->createExecution(
|
||||
projectId: $project->getId(),
|
||||
|
|
|
|||
|
|
@ -33,7 +33,15 @@ class Preview extends Adapter
|
|||
|
||||
$banner = <<<EOT
|
||||
<style>
|
||||
@import url(https://fonts.bunny.net/css?family=fira-code:400|inter:400);
|
||||
|
||||
#appwrite-preview {
|
||||
min-width: auto;
|
||||
min-height: auto;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
|
|
@ -80,7 +88,7 @@ class Preview extends Adapter
|
|||
padding: 0;
|
||||
margin: 0;
|
||||
color: var(--color-fgColor-neutral-secondary, #56565C);
|
||||
font-family: var(--font-family-sansSerif, Inter);
|
||||
font-family: var(--font-family-sansSerif, Inter), sans-serif;
|
||||
font-size: var(--font-size-XS, 12px);
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
|
|
@ -97,7 +105,7 @@ class Preview extends Adapter
|
|||
padding: var(--space-1, 2px) var(--space-2, 4px);
|
||||
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-XS, 12px);
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
|
|
@ -120,7 +128,7 @@ class Preview extends Adapter
|
|||
|
||||
#appwrite-preview-text {
|
||||
color: var(--color-fgColor-neutral-secondary, #C3C3C6);
|
||||
font-family: var(--font-family-sansSerif, Inter);
|
||||
font-family: var(--font-family-sansSerif, Inter), sans-serif;
|
||||
font-size: var(--font-size-XS, 12px);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,12 +71,18 @@ class Base extends Queries
|
|||
'array' => false,
|
||||
]);
|
||||
|
||||
$internalId = new Document([
|
||||
'key' => '$internalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'array' => false,
|
||||
]);
|
||||
|
||||
$validators = [
|
||||
new Limit(),
|
||||
new Offset(),
|
||||
new Cursor(),
|
||||
new Filter($attributes, APP_DATABASE_QUERY_MAX_VALUES),
|
||||
new Order($attributes),
|
||||
new Order([...$attributes, $internalId]),
|
||||
];
|
||||
|
||||
parent::__construct($validators);
|
||||
|
|
|
|||