mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge remote-tracking branch 'upstream/documents-db-api' into vector-db-api
This commit is contained in:
+15
-22
@@ -8,20 +8,13 @@ use Utopia\Config\Config;
|
||||
|
||||
$templateRuntimes = Config::getParam('template-runtimes');
|
||||
|
||||
function getVersions(array $versions, string $prefix)
|
||||
{
|
||||
return array_map(function ($version) use ($prefix) {
|
||||
return $prefix . '-' . $version;
|
||||
}, $versions);
|
||||
}
|
||||
|
||||
return [
|
||||
'analog' => [
|
||||
'key' => 'analog',
|
||||
'name' => 'Analog',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/analog/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/analog/env.sh',
|
||||
'adapters' => [
|
||||
@@ -47,7 +40,7 @@ return [
|
||||
'name' => 'Angular',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/angular/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/angular/env.sh',
|
||||
'adapters' => [
|
||||
@@ -73,7 +66,7 @@ return [
|
||||
'name' => 'Next.js',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/next-js/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/next-js/env.sh',
|
||||
'adapters' => [
|
||||
@@ -98,7 +91,7 @@ return [
|
||||
'name' => 'React',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
@@ -115,7 +108,7 @@ return [
|
||||
'name' => 'Nuxt',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/nuxt/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/nuxt/env.sh',
|
||||
'adapters' => [
|
||||
@@ -140,7 +133,7 @@ return [
|
||||
'name' => 'Vue.js',
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
@@ -157,7 +150,7 @@ return [
|
||||
'name' => 'SvelteKit',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/sveltekit/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/sveltekit/env.sh',
|
||||
'adapters' => [
|
||||
@@ -182,7 +175,7 @@ return [
|
||||
'name' => 'Astro',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/astro/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/astro/env.sh',
|
||||
'adapters' => [
|
||||
@@ -207,7 +200,7 @@ return [
|
||||
'name' => 'TanStack Start',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/tanstack-start/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/tanstack-start/env.sh',
|
||||
'adapters' => [
|
||||
@@ -232,7 +225,7 @@ return [
|
||||
'name' => 'Remix',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'bundleCommand' => 'bash /usr/local/server/helpers/remix/bundle.sh',
|
||||
'envCommand' => 'source /usr/local/server/helpers/remix/env.sh',
|
||||
'adapters' => [
|
||||
@@ -257,7 +250,7 @@ return [
|
||||
'name' => 'Lynx',
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
@@ -274,7 +267,7 @@ return [
|
||||
'name' => 'Flutter',
|
||||
'screenshotSleep' => 5000,
|
||||
'buildRuntime' => 'flutter-3.35',
|
||||
'runtimes' => getVersions($templateRuntimes['FLUTTER']['versions'], 'flutter'),
|
||||
'runtimes' => $templateRuntimes['FLUTTER'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
@@ -291,7 +284,7 @@ return [
|
||||
'name' => 'React Native',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
@@ -308,7 +301,7 @@ return [
|
||||
'name' => 'Vite',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
@@ -324,7 +317,7 @@ return [
|
||||
'name' => 'Other',
|
||||
'screenshotSleep' => 3000,
|
||||
'buildRuntime' => 'node-22',
|
||||
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
|
||||
'runtimes' => $templateRuntimes['NODE'],
|
||||
'adapters' => [
|
||||
'static' => [
|
||||
'key' => 'static',
|
||||
|
||||
+14
-14
@@ -11,7 +11,7 @@ return [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '21.4.0',
|
||||
'version' => '21.5.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -79,7 +79,7 @@ return [
|
||||
[
|
||||
'key' => 'apple',
|
||||
'name' => 'Apple',
|
||||
'version' => '13.4.0',
|
||||
'version' => '13.5.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'enabled' => true,
|
||||
@@ -116,7 +116,7 @@ return [
|
||||
[
|
||||
'key' => 'android',
|
||||
'name' => 'Android',
|
||||
'version' => '11.3.0',
|
||||
'version' => '11.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-android',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android',
|
||||
'enabled' => true,
|
||||
@@ -139,7 +139,7 @@ return [
|
||||
[
|
||||
'key' => 'react-native',
|
||||
'name' => 'React Native',
|
||||
'version' => '0.18.0',
|
||||
'version' => '0.19.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-react-native',
|
||||
'package' => 'https://npmjs.com/package/react-native-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -226,7 +226,7 @@ return [
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '12.0.0',
|
||||
'version' => '12.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
@@ -262,7 +262,7 @@ return [
|
||||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '20.3.0',
|
||||
'version' => '21.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -281,7 +281,7 @@ return [
|
||||
[
|
||||
'key' => 'php',
|
||||
'name' => 'PHP',
|
||||
'version' => '18.0.1',
|
||||
'version' => '19.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-php',
|
||||
'package' => 'https://packagist.org/packages/appwrite/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -300,7 +300,7 @@ return [
|
||||
[
|
||||
'key' => 'python',
|
||||
'name' => 'Python',
|
||||
'version' => '13.6.1',
|
||||
'version' => '14.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-python',
|
||||
'package' => 'https://pypi.org/project/appwrite/',
|
||||
'enabled' => true,
|
||||
@@ -319,7 +319,7 @@ return [
|
||||
[
|
||||
'key' => 'ruby',
|
||||
'name' => 'Ruby',
|
||||
'version' => '19.3.0',
|
||||
'version' => '20.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-ruby',
|
||||
'package' => 'https://rubygems.org/gems/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -338,7 +338,7 @@ return [
|
||||
[
|
||||
'key' => 'go',
|
||||
'name' => 'Go',
|
||||
'version' => 'v0.14.0',
|
||||
'version' => 'v0.15.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-go',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-go',
|
||||
'enabled' => true,
|
||||
@@ -357,7 +357,7 @@ return [
|
||||
[
|
||||
'key' => 'dotnet',
|
||||
'name' => '.NET',
|
||||
'version' => '0.22.0',
|
||||
'version' => '0.23.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
|
||||
'package' => 'https://www.nuget.org/packages/Appwrite',
|
||||
'enabled' => true,
|
||||
@@ -376,7 +376,7 @@ return [
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '19.4.0',
|
||||
'version' => '20.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
@@ -395,7 +395,7 @@ return [
|
||||
[
|
||||
'key' => 'kotlin',
|
||||
'name' => 'Kotlin',
|
||||
'version' => '12.3.0',
|
||||
'version' => '13.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
|
||||
'enabled' => true,
|
||||
@@ -418,7 +418,7 @@ return [
|
||||
[
|
||||
'key' => 'swift',
|
||||
'name' => 'Swift',
|
||||
'version' => '13.3.0',
|
||||
'version' => '14.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'enabled' => true,
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listIdentities",
|
||||
"group": "identities",
|
||||
"weight": 58,
|
||||
"weight": 48,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-identities.md",
|
||||
@@ -328,7 +328,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteIdentity",
|
||||
"group": "identities",
|
||||
"weight": 59,
|
||||
"weight": 49,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-identity.md",
|
||||
@@ -517,7 +517,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMFA",
|
||||
"group": "mfa",
|
||||
"weight": 45,
|
||||
"weight": 306,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa.md",
|
||||
@@ -587,7 +587,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 47,
|
||||
"weight": 308,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-authenticator.md",
|
||||
@@ -707,7 +707,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 48,
|
||||
"weight": 309,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-authenticator.md",
|
||||
@@ -843,7 +843,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 52,
|
||||
"weight": 310,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-mfa-authenticator.md",
|
||||
@@ -939,7 +939,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/account\/mfa\/challenge": {
|
||||
"\/account\/mfa\/challenges": {
|
||||
"post": {
|
||||
"summary": "Create MFA challenge",
|
||||
"operationId": "accountCreateMfaChallenge",
|
||||
@@ -963,7 +963,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 53,
|
||||
"weight": 314,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-challenge.md",
|
||||
@@ -1091,7 +1091,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 54,
|
||||
"weight": 315,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-challenge.md",
|
||||
@@ -1225,7 +1225,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMfaFactors",
|
||||
"group": "mfa",
|
||||
"weight": 46,
|
||||
"weight": 307,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-mfa-factors.md",
|
||||
@@ -1322,7 +1322,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 51,
|
||||
"weight": 313,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/get-mfa-recovery-codes.md",
|
||||
@@ -1417,7 +1417,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 49,
|
||||
"weight": 311,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-recovery-codes.md",
|
||||
@@ -1512,7 +1512,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 50,
|
||||
"weight": 312,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-recovery-codes.md",
|
||||
@@ -2918,7 +2918,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createPushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 55,
|
||||
"weight": 45,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-push-target.md",
|
||||
@@ -2997,7 +2997,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 56,
|
||||
"weight": 46,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-push-target.md",
|
||||
@@ -3068,7 +3068,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deletePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 57,
|
||||
"weight": 47,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-push-target.md",
|
||||
@@ -3879,7 +3879,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getBrowser",
|
||||
"group": null,
|
||||
"weight": 61,
|
||||
"weight": 51,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-browser.md",
|
||||
@@ -4005,7 +4005,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getCreditCard",
|
||||
"group": null,
|
||||
"weight": 60,
|
||||
"weight": 50,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-credit-card.md",
|
||||
@@ -4137,7 +4137,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFavicon",
|
||||
"group": null,
|
||||
"weight": 64,
|
||||
"weight": 54,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-favicon.md",
|
||||
@@ -4195,7 +4195,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFlag",
|
||||
"group": null,
|
||||
"weight": 62,
|
||||
"weight": 52,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-flag.md",
|
||||
@@ -4683,7 +4683,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getImage",
|
||||
"group": null,
|
||||
"weight": 63,
|
||||
"weight": 53,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-image.md",
|
||||
@@ -4765,7 +4765,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getInitials",
|
||||
"group": null,
|
||||
"weight": 66,
|
||||
"weight": 56,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-initials.md",
|
||||
@@ -4857,7 +4857,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getQR",
|
||||
"group": null,
|
||||
"weight": 65,
|
||||
"weight": 55,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-qr.md",
|
||||
@@ -4949,7 +4949,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getScreenshot",
|
||||
"group": null,
|
||||
"weight": 67,
|
||||
"weight": 57,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-screenshot.md",
|
||||
@@ -4993,7 +4993,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"x-example": "{}",
|
||||
"x-example": "{\"Authorization\":\"Bearer token123\",\"X-Custom-Header\":\"value\"}",
|
||||
"default": {}
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5005,7 +5005,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1920",
|
||||
"default": 1280
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5017,7 +5017,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1080",
|
||||
"default": 720
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5029,7 +5029,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0.1,
|
||||
"x-example": "2",
|
||||
"default": 1
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5040,7 +5040,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "light",
|
||||
"x-example": "dark",
|
||||
"enum": [
|
||||
"light",
|
||||
"dark"
|
||||
@@ -5057,7 +5057,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<USER_AGENT>",
|
||||
"x-example": "Mozilla\/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit\/605.1.15",
|
||||
"default": ""
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5068,7 +5068,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5079,7 +5079,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<LOCALE>",
|
||||
"x-example": "en-US",
|
||||
"default": ""
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5090,7 +5090,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "africa\/abidjan",
|
||||
"x-example": "america\/new_york",
|
||||
"enum": [
|
||||
"africa\/abidjan",
|
||||
"africa\/accra",
|
||||
@@ -5525,7 +5525,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -90,
|
||||
"x-example": "37.7749",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5537,7 +5537,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -180,
|
||||
"x-example": "-122.4194",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5549,7 +5549,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0,
|
||||
"x-example": "100",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5560,7 +5560,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5572,8 +5572,33 @@
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"geolocation",
|
||||
"camera",
|
||||
"microphone",
|
||||
"notifications",
|
||||
"midi",
|
||||
"push",
|
||||
"clipboard-read",
|
||||
"clipboard-write",
|
||||
"payment-handler",
|
||||
"usb",
|
||||
"bluetooth",
|
||||
"accelerometer",
|
||||
"gyroscope",
|
||||
"magnetometer",
|
||||
"ambient-light-sensor",
|
||||
"background-sync",
|
||||
"persistent-storage",
|
||||
"screen-wake-lock",
|
||||
"web-share",
|
||||
"xr-spatial-tracking"
|
||||
],
|
||||
"x-enum-name": "BrowserPermission",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"x-example": "[\"geolocation\",\"notifications\"]",
|
||||
"default": []
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5585,7 +5610,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "3",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5597,7 +5622,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "800",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5609,7 +5634,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "600",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5621,7 +5646,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": -1,
|
||||
"x-example": "85",
|
||||
"default": -1
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5632,7 +5657,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "jpg",
|
||||
"x-example": "jpeg",
|
||||
"enum": [
|
||||
"jpg",
|
||||
"jpeg",
|
||||
@@ -7370,7 +7395,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "query",
|
||||
"group": "graphql",
|
||||
"weight": 251,
|
||||
"weight": 241,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/query.md",
|
||||
@@ -7422,7 +7447,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "mutation",
|
||||
"group": "graphql",
|
||||
"weight": 250,
|
||||
"weight": 240,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/mutation.md",
|
||||
@@ -7474,7 +7499,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": null,
|
||||
"weight": 71,
|
||||
"weight": 61,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/get.md",
|
||||
@@ -7526,7 +7551,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCodes",
|
||||
"group": null,
|
||||
"weight": 72,
|
||||
"weight": 62,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-codes.md",
|
||||
@@ -7578,7 +7603,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listContinents",
|
||||
"group": null,
|
||||
"weight": 76,
|
||||
"weight": 66,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-continents.md",
|
||||
@@ -7630,7 +7655,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountries",
|
||||
"group": null,
|
||||
"weight": 73,
|
||||
"weight": 63,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries.md",
|
||||
@@ -7682,7 +7707,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesEU",
|
||||
"group": null,
|
||||
"weight": 74,
|
||||
"weight": 64,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-eu.md",
|
||||
@@ -7734,7 +7759,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesPhones",
|
||||
"group": null,
|
||||
"weight": 75,
|
||||
"weight": 65,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-phones.md",
|
||||
@@ -7786,7 +7811,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCurrencies",
|
||||
"group": null,
|
||||
"weight": 77,
|
||||
"weight": 67,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-currencies.md",
|
||||
@@ -7838,7 +7863,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listLanguages",
|
||||
"group": null,
|
||||
"weight": 78,
|
||||
"weight": 68,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-languages.md",
|
||||
@@ -7890,7 +7915,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 300,
|
||||
"weight": 290,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/create-subscriber.md",
|
||||
@@ -7973,7 +7998,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 304,
|
||||
"weight": 294,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/delete-subscriber.md",
|
||||
@@ -8048,7 +8073,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listFiles",
|
||||
"group": "files",
|
||||
"weight": 161,
|
||||
"weight": 151,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/list-files.md",
|
||||
@@ -8145,7 +8170,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createFile",
|
||||
"group": "files",
|
||||
"weight": 160,
|
||||
"weight": 150,
|
||||
"cookies": false,
|
||||
"type": "upload",
|
||||
"demo": "storage\/create-file.md",
|
||||
@@ -8244,7 +8269,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFile",
|
||||
"group": "files",
|
||||
"weight": 162,
|
||||
"weight": 152,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/get-file.md",
|
||||
@@ -8316,7 +8341,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateFile",
|
||||
"group": "files",
|
||||
"weight": 167,
|
||||
"weight": 157,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/update-file.md",
|
||||
@@ -8407,7 +8432,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteFile",
|
||||
"group": "files",
|
||||
"weight": 168,
|
||||
"weight": 158,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/delete-file.md",
|
||||
@@ -8474,7 +8499,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileDownload",
|
||||
"group": "files",
|
||||
"weight": 164,
|
||||
"weight": 154,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-download.md",
|
||||
@@ -8552,7 +8577,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFilePreview",
|
||||
"group": "files",
|
||||
"weight": 163,
|
||||
"weight": 153,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-preview.md",
|
||||
@@ -8780,7 +8805,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileView",
|
||||
"group": "files",
|
||||
"weight": 165,
|
||||
"weight": 155,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-view.md",
|
||||
@@ -10281,7 +10306,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "list",
|
||||
"group": "teams",
|
||||
"weight": 172,
|
||||
"weight": 162,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list.md",
|
||||
@@ -10368,7 +10393,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "create",
|
||||
"group": "teams",
|
||||
"weight": 171,
|
||||
"weight": 161,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create.md",
|
||||
@@ -10453,7 +10478,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": "teams",
|
||||
"weight": 173,
|
||||
"weight": 163,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get.md",
|
||||
@@ -10515,7 +10540,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateName",
|
||||
"group": "teams",
|
||||
"weight": 175,
|
||||
"weight": 165,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-name.md",
|
||||
@@ -10589,7 +10614,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "delete",
|
||||
"group": "teams",
|
||||
"weight": 177,
|
||||
"weight": 167,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete.md",
|
||||
@@ -10653,7 +10678,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMemberships",
|
||||
"group": "memberships",
|
||||
"weight": 179,
|
||||
"weight": 169,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list-memberships.md",
|
||||
@@ -10750,7 +10775,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMembership",
|
||||
"group": "memberships",
|
||||
"weight": 178,
|
||||
"weight": 168,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create-membership.md",
|
||||
@@ -10814,7 +10839,14 @@
|
||||
"description": "Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions). Maximum of 100 roles are allowed, each 32 characters long.",
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
@@ -10861,7 +10893,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMembership",
|
||||
"group": "memberships",
|
||||
"weight": 180,
|
||||
"weight": 170,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-membership.md",
|
||||
@@ -10933,7 +10965,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembership",
|
||||
"group": "memberships",
|
||||
"weight": 181,
|
||||
"weight": 171,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership.md",
|
||||
@@ -10992,7 +11024,14 @@
|
||||
"description": "An array of strings. Use this param to set the user's roles in the team. A role can be any string. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions). Maximum of 100 roles are allowed, each 32 characters long.",
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11020,7 +11059,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMembership",
|
||||
"group": "memberships",
|
||||
"weight": 183,
|
||||
"weight": 173,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete-membership.md",
|
||||
@@ -11094,7 +11133,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembershipStatus",
|
||||
"group": "memberships",
|
||||
"weight": 182,
|
||||
"weight": 172,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership-status.md",
|
||||
@@ -11192,7 +11231,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getPrefs",
|
||||
"group": "teams",
|
||||
"weight": 174,
|
||||
"weight": 164,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-prefs.md",
|
||||
@@ -11253,7 +11292,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePrefs",
|
||||
"group": "teams",
|
||||
"weight": 176,
|
||||
"weight": 166,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-prefs.md",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -258,7 +258,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listIdentities",
|
||||
"group": "identities",
|
||||
"weight": 58,
|
||||
"weight": 48,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-identities.md",
|
||||
@@ -328,7 +328,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteIdentity",
|
||||
"group": "identities",
|
||||
"weight": 59,
|
||||
"weight": 49,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-identity.md",
|
||||
@@ -517,7 +517,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMFA",
|
||||
"group": "mfa",
|
||||
"weight": 45,
|
||||
"weight": 306,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa.md",
|
||||
@@ -587,7 +587,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 47,
|
||||
"weight": 308,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-authenticator.md",
|
||||
@@ -707,7 +707,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 48,
|
||||
"weight": 309,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-authenticator.md",
|
||||
@@ -843,7 +843,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 52,
|
||||
"weight": 310,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-mfa-authenticator.md",
|
||||
@@ -939,7 +939,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/account\/mfa\/challenge": {
|
||||
"\/account\/mfa\/challenges": {
|
||||
"post": {
|
||||
"summary": "Create MFA challenge",
|
||||
"operationId": "accountCreateMfaChallenge",
|
||||
@@ -963,7 +963,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 53,
|
||||
"weight": 314,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-challenge.md",
|
||||
@@ -1091,7 +1091,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 54,
|
||||
"weight": 315,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-challenge.md",
|
||||
@@ -1225,7 +1225,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMfaFactors",
|
||||
"group": "mfa",
|
||||
"weight": 46,
|
||||
"weight": 307,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-mfa-factors.md",
|
||||
@@ -1322,7 +1322,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 51,
|
||||
"weight": 313,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/get-mfa-recovery-codes.md",
|
||||
@@ -1417,7 +1417,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 49,
|
||||
"weight": 311,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-recovery-codes.md",
|
||||
@@ -1512,7 +1512,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 50,
|
||||
"weight": 312,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-recovery-codes.md",
|
||||
@@ -2918,7 +2918,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createPushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 55,
|
||||
"weight": 45,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-push-target.md",
|
||||
@@ -2997,7 +2997,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 56,
|
||||
"weight": 46,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-push-target.md",
|
||||
@@ -3068,7 +3068,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deletePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 57,
|
||||
"weight": 47,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-push-target.md",
|
||||
@@ -3879,7 +3879,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getBrowser",
|
||||
"group": null,
|
||||
"weight": 61,
|
||||
"weight": 51,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-browser.md",
|
||||
@@ -4005,7 +4005,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getCreditCard",
|
||||
"group": null,
|
||||
"weight": 60,
|
||||
"weight": 50,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-credit-card.md",
|
||||
@@ -4137,7 +4137,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFavicon",
|
||||
"group": null,
|
||||
"weight": 64,
|
||||
"weight": 54,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-favicon.md",
|
||||
@@ -4195,7 +4195,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFlag",
|
||||
"group": null,
|
||||
"weight": 62,
|
||||
"weight": 52,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-flag.md",
|
||||
@@ -4683,7 +4683,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getImage",
|
||||
"group": null,
|
||||
"weight": 63,
|
||||
"weight": 53,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-image.md",
|
||||
@@ -4765,7 +4765,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getInitials",
|
||||
"group": null,
|
||||
"weight": 66,
|
||||
"weight": 56,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-initials.md",
|
||||
@@ -4857,7 +4857,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getQR",
|
||||
"group": null,
|
||||
"weight": 65,
|
||||
"weight": 55,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-qr.md",
|
||||
@@ -4949,7 +4949,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getScreenshot",
|
||||
"group": null,
|
||||
"weight": 67,
|
||||
"weight": 57,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-screenshot.md",
|
||||
@@ -4993,7 +4993,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"x-example": "{}",
|
||||
"x-example": "{\"Authorization\":\"Bearer token123\",\"X-Custom-Header\":\"value\"}",
|
||||
"default": {}
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5005,7 +5005,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1920",
|
||||
"default": 1280
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5017,7 +5017,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1080",
|
||||
"default": 720
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5029,7 +5029,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0.1,
|
||||
"x-example": "2",
|
||||
"default": 1
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5040,7 +5040,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "light",
|
||||
"x-example": "dark",
|
||||
"enum": [
|
||||
"light",
|
||||
"dark"
|
||||
@@ -5057,7 +5057,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<USER_AGENT>",
|
||||
"x-example": "Mozilla\/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit\/605.1.15",
|
||||
"default": ""
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5068,7 +5068,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5079,7 +5079,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "<LOCALE>",
|
||||
"x-example": "en-US",
|
||||
"default": ""
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5090,7 +5090,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "africa\/abidjan",
|
||||
"x-example": "america\/new_york",
|
||||
"enum": [
|
||||
"africa\/abidjan",
|
||||
"africa\/accra",
|
||||
@@ -5525,7 +5525,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -90,
|
||||
"x-example": "37.7749",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5537,7 +5537,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -180,
|
||||
"x-example": "-122.4194",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5549,7 +5549,7 @@
|
||||
"schema": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0,
|
||||
"x-example": "100",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5560,7 +5560,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5572,8 +5572,33 @@
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"geolocation",
|
||||
"camera",
|
||||
"microphone",
|
||||
"notifications",
|
||||
"midi",
|
||||
"push",
|
||||
"clipboard-read",
|
||||
"clipboard-write",
|
||||
"payment-handler",
|
||||
"usb",
|
||||
"bluetooth",
|
||||
"accelerometer",
|
||||
"gyroscope",
|
||||
"magnetometer",
|
||||
"ambient-light-sensor",
|
||||
"background-sync",
|
||||
"persistent-storage",
|
||||
"screen-wake-lock",
|
||||
"web-share",
|
||||
"xr-spatial-tracking"
|
||||
],
|
||||
"x-enum-name": "BrowserPermission",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"x-example": "[\"geolocation\",\"notifications\"]",
|
||||
"default": []
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5585,7 +5610,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "3",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5597,7 +5622,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "800",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5609,7 +5634,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "600",
|
||||
"default": 0
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5621,7 +5646,7 @@
|
||||
"schema": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": -1,
|
||||
"x-example": "85",
|
||||
"default": -1
|
||||
},
|
||||
"in": "query"
|
||||
@@ -5632,7 +5657,7 @@
|
||||
"required": false,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"x-example": "jpg",
|
||||
"x-example": "jpeg",
|
||||
"enum": [
|
||||
"jpg",
|
||||
"jpeg",
|
||||
@@ -7370,7 +7395,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "query",
|
||||
"group": "graphql",
|
||||
"weight": 251,
|
||||
"weight": 241,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/query.md",
|
||||
@@ -7422,7 +7447,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "mutation",
|
||||
"group": "graphql",
|
||||
"weight": 250,
|
||||
"weight": 240,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/mutation.md",
|
||||
@@ -7474,7 +7499,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": null,
|
||||
"weight": 71,
|
||||
"weight": 61,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/get.md",
|
||||
@@ -7526,7 +7551,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCodes",
|
||||
"group": null,
|
||||
"weight": 72,
|
||||
"weight": 62,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-codes.md",
|
||||
@@ -7578,7 +7603,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listContinents",
|
||||
"group": null,
|
||||
"weight": 76,
|
||||
"weight": 66,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-continents.md",
|
||||
@@ -7630,7 +7655,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountries",
|
||||
"group": null,
|
||||
"weight": 73,
|
||||
"weight": 63,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries.md",
|
||||
@@ -7682,7 +7707,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesEU",
|
||||
"group": null,
|
||||
"weight": 74,
|
||||
"weight": 64,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-eu.md",
|
||||
@@ -7734,7 +7759,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesPhones",
|
||||
"group": null,
|
||||
"weight": 75,
|
||||
"weight": 65,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-phones.md",
|
||||
@@ -7786,7 +7811,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCurrencies",
|
||||
"group": null,
|
||||
"weight": 77,
|
||||
"weight": 67,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-currencies.md",
|
||||
@@ -7838,7 +7863,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listLanguages",
|
||||
"group": null,
|
||||
"weight": 78,
|
||||
"weight": 68,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-languages.md",
|
||||
@@ -7890,7 +7915,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 300,
|
||||
"weight": 290,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/create-subscriber.md",
|
||||
@@ -7973,7 +7998,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 304,
|
||||
"weight": 294,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/delete-subscriber.md",
|
||||
@@ -8048,7 +8073,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listFiles",
|
||||
"group": "files",
|
||||
"weight": 161,
|
||||
"weight": 151,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/list-files.md",
|
||||
@@ -8145,7 +8170,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createFile",
|
||||
"group": "files",
|
||||
"weight": 160,
|
||||
"weight": 150,
|
||||
"cookies": false,
|
||||
"type": "upload",
|
||||
"demo": "storage\/create-file.md",
|
||||
@@ -8244,7 +8269,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFile",
|
||||
"group": "files",
|
||||
"weight": 162,
|
||||
"weight": 152,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/get-file.md",
|
||||
@@ -8316,7 +8341,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateFile",
|
||||
"group": "files",
|
||||
"weight": 167,
|
||||
"weight": 157,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/update-file.md",
|
||||
@@ -8407,7 +8432,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteFile",
|
||||
"group": "files",
|
||||
"weight": 168,
|
||||
"weight": 158,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/delete-file.md",
|
||||
@@ -8474,7 +8499,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileDownload",
|
||||
"group": "files",
|
||||
"weight": 164,
|
||||
"weight": 154,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-download.md",
|
||||
@@ -8552,7 +8577,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFilePreview",
|
||||
"group": "files",
|
||||
"weight": 163,
|
||||
"weight": 153,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-preview.md",
|
||||
@@ -8780,7 +8805,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileView",
|
||||
"group": "files",
|
||||
"weight": 165,
|
||||
"weight": 155,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-view.md",
|
||||
@@ -10281,7 +10306,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "list",
|
||||
"group": "teams",
|
||||
"weight": 172,
|
||||
"weight": 162,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list.md",
|
||||
@@ -10368,7 +10393,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "create",
|
||||
"group": "teams",
|
||||
"weight": 171,
|
||||
"weight": 161,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create.md",
|
||||
@@ -10453,7 +10478,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": "teams",
|
||||
"weight": 173,
|
||||
"weight": 163,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get.md",
|
||||
@@ -10515,7 +10540,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateName",
|
||||
"group": "teams",
|
||||
"weight": 175,
|
||||
"weight": 165,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-name.md",
|
||||
@@ -10589,7 +10614,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "delete",
|
||||
"group": "teams",
|
||||
"weight": 177,
|
||||
"weight": 167,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete.md",
|
||||
@@ -10653,7 +10678,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMemberships",
|
||||
"group": "memberships",
|
||||
"weight": 179,
|
||||
"weight": 169,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list-memberships.md",
|
||||
@@ -10750,7 +10775,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMembership",
|
||||
"group": "memberships",
|
||||
"weight": 178,
|
||||
"weight": 168,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create-membership.md",
|
||||
@@ -10814,7 +10839,14 @@
|
||||
"description": "Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions). Maximum of 100 roles are allowed, each 32 characters long.",
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
@@ -10861,7 +10893,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMembership",
|
||||
"group": "memberships",
|
||||
"weight": 180,
|
||||
"weight": 170,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-membership.md",
|
||||
@@ -10933,7 +10965,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembership",
|
||||
"group": "memberships",
|
||||
"weight": 181,
|
||||
"weight": 171,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership.md",
|
||||
@@ -10992,7 +11024,14 @@
|
||||
"description": "An array of strings. Use this param to set the user's roles in the team. A role can be any string. Learn more about [roles and permissions](https:\/\/appwrite.io\/docs\/permissions). Maximum of 100 roles are allowed, each 32 characters long.",
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -11020,7 +11059,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMembership",
|
||||
"group": "memberships",
|
||||
"weight": 183,
|
||||
"weight": 173,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete-membership.md",
|
||||
@@ -11094,7 +11133,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembershipStatus",
|
||||
"group": "memberships",
|
||||
"weight": 182,
|
||||
"weight": 172,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership-status.md",
|
||||
@@ -11192,7 +11231,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getPrefs",
|
||||
"group": "teams",
|
||||
"weight": 174,
|
||||
"weight": 164,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-prefs.md",
|
||||
@@ -11253,7 +11292,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePrefs",
|
||||
"group": "teams",
|
||||
"weight": 176,
|
||||
"weight": 166,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-prefs.md",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -314,7 +314,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listIdentities",
|
||||
"group": "identities",
|
||||
"weight": 58,
|
||||
"weight": 48,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-identities.md",
|
||||
@@ -385,7 +385,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteIdentity",
|
||||
"group": "identities",
|
||||
"weight": 59,
|
||||
"weight": 49,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-identity.md",
|
||||
@@ -573,7 +573,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMFA",
|
||||
"group": "mfa",
|
||||
"weight": 45,
|
||||
"weight": 306,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa.md",
|
||||
@@ -646,7 +646,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 47,
|
||||
"weight": 308,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-authenticator.md",
|
||||
@@ -766,7 +766,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 48,
|
||||
"weight": 309,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-authenticator.md",
|
||||
@@ -903,7 +903,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 52,
|
||||
"weight": 310,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-mfa-authenticator.md",
|
||||
@@ -997,7 +997,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/account\/mfa\/challenge": {
|
||||
"\/account\/mfa\/challenges": {
|
||||
"post": {
|
||||
"summary": "Create MFA challenge",
|
||||
"operationId": "accountCreateMfaChallenge",
|
||||
@@ -1023,7 +1023,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 53,
|
||||
"weight": 314,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-challenge.md",
|
||||
@@ -1154,7 +1154,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 54,
|
||||
"weight": 315,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-challenge.md",
|
||||
@@ -1290,7 +1290,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMfaFactors",
|
||||
"group": "mfa",
|
||||
"weight": 46,
|
||||
"weight": 307,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-mfa-factors.md",
|
||||
@@ -1387,7 +1387,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 51,
|
||||
"weight": 313,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/get-mfa-recovery-codes.md",
|
||||
@@ -1484,7 +1484,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 49,
|
||||
"weight": 311,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-recovery-codes.md",
|
||||
@@ -1581,7 +1581,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 50,
|
||||
"weight": 312,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-recovery-codes.md",
|
||||
@@ -3033,7 +3033,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createPushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 55,
|
||||
"weight": 45,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-push-target.md",
|
||||
@@ -3117,7 +3117,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 56,
|
||||
"weight": 46,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-push-target.md",
|
||||
@@ -3189,7 +3189,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deletePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 57,
|
||||
"weight": 47,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-push-target.md",
|
||||
@@ -4030,7 +4030,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getBrowser",
|
||||
"group": null,
|
||||
"weight": 61,
|
||||
"weight": 51,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-browser.md",
|
||||
@@ -4154,7 +4154,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getCreditCard",
|
||||
"group": null,
|
||||
"weight": 60,
|
||||
"weight": 50,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-credit-card.md",
|
||||
@@ -4284,7 +4284,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFavicon",
|
||||
"group": null,
|
||||
"weight": 64,
|
||||
"weight": 54,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-favicon.md",
|
||||
@@ -4346,7 +4346,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFlag",
|
||||
"group": null,
|
||||
"weight": 62,
|
||||
"weight": 52,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-flag.md",
|
||||
@@ -4832,7 +4832,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getImage",
|
||||
"group": null,
|
||||
"weight": 63,
|
||||
"weight": 53,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-image.md",
|
||||
@@ -4914,7 +4914,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getInitials",
|
||||
"group": null,
|
||||
"weight": 66,
|
||||
"weight": 56,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-initials.md",
|
||||
@@ -5004,7 +5004,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getQR",
|
||||
"group": null,
|
||||
"weight": 65,
|
||||
"weight": 55,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-qr.md",
|
||||
@@ -5094,7 +5094,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getScreenshot",
|
||||
"group": null,
|
||||
"weight": 67,
|
||||
"weight": 57,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-screenshot.md",
|
||||
@@ -5135,7 +5135,7 @@
|
||||
"required": false,
|
||||
"type": "object",
|
||||
"default": [],
|
||||
"x-example": "{}",
|
||||
"x-example": "{\"Authorization\":\"Bearer token123\",\"X-Custom-Header\":\"value\"}",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
@@ -5144,7 +5144,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1920",
|
||||
"default": 1280,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5154,7 +5154,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1080",
|
||||
"default": 720,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5164,7 +5164,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0.1,
|
||||
"x-example": "2",
|
||||
"default": 1,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5173,7 +5173,7 @@
|
||||
"description": "Browser theme. Pass \"light\" or \"dark\". Defaults to \"light\".",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "light",
|
||||
"x-example": "dark",
|
||||
"enum": [
|
||||
"light",
|
||||
"dark"
|
||||
@@ -5188,7 +5188,7 @@
|
||||
"description": "Custom user agent string. Defaults to browser default.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "<USER_AGENT>",
|
||||
"x-example": "Mozilla\/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit\/605.1.15",
|
||||
"default": "",
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5197,7 +5197,7 @@
|
||||
"description": "Capture full page scroll. Pass 0 for viewport only, or 1 for full page. Defaults to 0.",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5206,7 +5206,7 @@
|
||||
"description": "Browser locale (e.g., \"en-US\", \"fr-FR\"). Defaults to browser default.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "<LOCALE>",
|
||||
"x-example": "en-US",
|
||||
"default": "",
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5215,7 +5215,7 @@
|
||||
"description": "IANA timezone identifier (e.g., \"America\/New_York\", \"Europe\/London\"). Defaults to browser default.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "africa\/abidjan",
|
||||
"x-example": "america\/new_york",
|
||||
"enum": [
|
||||
"africa\/abidjan",
|
||||
"africa\/accra",
|
||||
@@ -5648,7 +5648,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -90,
|
||||
"x-example": "37.7749",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5658,7 +5658,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -180,
|
||||
"x-example": "-122.4194",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5668,7 +5668,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0,
|
||||
"x-example": "100",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5677,7 +5677,7 @@
|
||||
"description": "Enable touch support. Pass 0 for no touch, or 1 for touch enabled. Defaults to 0.",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5688,8 +5688,33 @@
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"geolocation",
|
||||
"camera",
|
||||
"microphone",
|
||||
"notifications",
|
||||
"midi",
|
||||
"push",
|
||||
"clipboard-read",
|
||||
"clipboard-write",
|
||||
"payment-handler",
|
||||
"usb",
|
||||
"bluetooth",
|
||||
"accelerometer",
|
||||
"gyroscope",
|
||||
"magnetometer",
|
||||
"ambient-light-sensor",
|
||||
"background-sync",
|
||||
"persistent-storage",
|
||||
"screen-wake-lock",
|
||||
"web-share",
|
||||
"xr-spatial-tracking"
|
||||
],
|
||||
"x-enum-name": "BrowserPermission",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"x-example": "[\"geolocation\",\"notifications\"]",
|
||||
"default": [],
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5699,7 +5724,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "3",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5709,7 +5734,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "800",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5719,7 +5744,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "600",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5729,7 +5754,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": -1,
|
||||
"x-example": "85",
|
||||
"default": -1,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5738,7 +5763,7 @@
|
||||
"description": "Output format type (jpeg, jpg, png, gif and webp).",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "jpg",
|
||||
"x-example": "jpeg",
|
||||
"enum": [
|
||||
"jpg",
|
||||
"jpeg",
|
||||
@@ -7420,7 +7445,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "query",
|
||||
"group": "graphql",
|
||||
"weight": 251,
|
||||
"weight": 241,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/query.md",
|
||||
@@ -7493,7 +7518,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "mutation",
|
||||
"group": "graphql",
|
||||
"weight": 250,
|
||||
"weight": 240,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/mutation.md",
|
||||
@@ -7564,7 +7589,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": null,
|
||||
"weight": 71,
|
||||
"weight": 61,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/get.md",
|
||||
@@ -7615,7 +7640,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCodes",
|
||||
"group": null,
|
||||
"weight": 72,
|
||||
"weight": 62,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-codes.md",
|
||||
@@ -7666,7 +7691,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listContinents",
|
||||
"group": null,
|
||||
"weight": 76,
|
||||
"weight": 66,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-continents.md",
|
||||
@@ -7717,7 +7742,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountries",
|
||||
"group": null,
|
||||
"weight": 73,
|
||||
"weight": 63,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries.md",
|
||||
@@ -7768,7 +7793,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesEU",
|
||||
"group": null,
|
||||
"weight": 74,
|
||||
"weight": 64,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-eu.md",
|
||||
@@ -7819,7 +7844,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesPhones",
|
||||
"group": null,
|
||||
"weight": 75,
|
||||
"weight": 65,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-phones.md",
|
||||
@@ -7870,7 +7895,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCurrencies",
|
||||
"group": null,
|
||||
"weight": 77,
|
||||
"weight": 67,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-currencies.md",
|
||||
@@ -7921,7 +7946,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listLanguages",
|
||||
"group": null,
|
||||
"weight": 78,
|
||||
"weight": 68,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-languages.md",
|
||||
@@ -7974,7 +7999,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 300,
|
||||
"weight": 290,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/create-subscriber.md",
|
||||
@@ -8058,7 +8083,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 304,
|
||||
"weight": 294,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/delete-subscriber.md",
|
||||
@@ -8128,7 +8153,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listFiles",
|
||||
"group": "files",
|
||||
"weight": 161,
|
||||
"weight": 151,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/list-files.md",
|
||||
@@ -8219,7 +8244,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createFile",
|
||||
"group": "files",
|
||||
"weight": 160,
|
||||
"weight": 150,
|
||||
"cookies": false,
|
||||
"type": "upload",
|
||||
"demo": "storage\/create-file.md",
|
||||
@@ -8308,7 +8333,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFile",
|
||||
"group": "files",
|
||||
"weight": 162,
|
||||
"weight": 152,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/get-file.md",
|
||||
@@ -8377,7 +8402,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateFile",
|
||||
"group": "files",
|
||||
"weight": 167,
|
||||
"weight": 157,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/update-file.md",
|
||||
@@ -8467,7 +8492,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteFile",
|
||||
"group": "files",
|
||||
"weight": 168,
|
||||
"weight": 158,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/delete-file.md",
|
||||
@@ -8536,7 +8561,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileDownload",
|
||||
"group": "files",
|
||||
"weight": 164,
|
||||
"weight": 154,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-download.md",
|
||||
@@ -8614,7 +8639,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFilePreview",
|
||||
"group": "files",
|
||||
"weight": 163,
|
||||
"weight": 153,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-preview.md",
|
||||
@@ -8820,7 +8845,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileView",
|
||||
"group": "files",
|
||||
"weight": 165,
|
||||
"weight": 155,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-view.md",
|
||||
@@ -10265,7 +10290,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "list",
|
||||
"group": "teams",
|
||||
"weight": 172,
|
||||
"weight": 162,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list.md",
|
||||
@@ -10348,7 +10373,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "create",
|
||||
"group": "teams",
|
||||
"weight": 171,
|
||||
"weight": 161,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create.md",
|
||||
@@ -10437,7 +10462,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": "teams",
|
||||
"weight": 173,
|
||||
"weight": 163,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get.md",
|
||||
@@ -10498,7 +10523,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateName",
|
||||
"group": "teams",
|
||||
"weight": 175,
|
||||
"weight": 165,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-name.md",
|
||||
@@ -10572,7 +10597,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "delete",
|
||||
"group": "teams",
|
||||
"weight": 177,
|
||||
"weight": 167,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete.md",
|
||||
@@ -10633,7 +10658,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMemberships",
|
||||
"group": "memberships",
|
||||
"weight": 179,
|
||||
"weight": 169,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list-memberships.md",
|
||||
@@ -10724,7 +10749,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMembership",
|
||||
"group": "memberships",
|
||||
"weight": 178,
|
||||
"weight": 168,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create-membership.md",
|
||||
@@ -10788,7 +10813,14 @@
|
||||
"default": null,
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
@@ -10836,7 +10868,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMembership",
|
||||
"group": "memberships",
|
||||
"weight": 180,
|
||||
"weight": 170,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-membership.md",
|
||||
@@ -10905,7 +10937,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembership",
|
||||
"group": "memberships",
|
||||
"weight": 181,
|
||||
"weight": 171,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership.md",
|
||||
@@ -10959,7 +10991,14 @@
|
||||
"default": null,
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10990,7 +11029,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMembership",
|
||||
"group": "memberships",
|
||||
"weight": 183,
|
||||
"weight": 173,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete-membership.md",
|
||||
@@ -11061,7 +11100,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembershipStatus",
|
||||
"group": "memberships",
|
||||
"weight": 182,
|
||||
"weight": 172,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership-status.md",
|
||||
@@ -11155,7 +11194,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getPrefs",
|
||||
"group": "teams",
|
||||
"weight": 174,
|
||||
"weight": 164,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-prefs.md",
|
||||
@@ -11216,7 +11255,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePrefs",
|
||||
"group": "teams",
|
||||
"weight": 176,
|
||||
"weight": 166,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-prefs.md",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -314,7 +314,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listIdentities",
|
||||
"group": "identities",
|
||||
"weight": 58,
|
||||
"weight": 48,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-identities.md",
|
||||
@@ -385,7 +385,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteIdentity",
|
||||
"group": "identities",
|
||||
"weight": 59,
|
||||
"weight": 49,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-identity.md",
|
||||
@@ -573,7 +573,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMFA",
|
||||
"group": "mfa",
|
||||
"weight": 45,
|
||||
"weight": 306,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa.md",
|
||||
@@ -646,7 +646,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 47,
|
||||
"weight": 308,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-authenticator.md",
|
||||
@@ -766,7 +766,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 48,
|
||||
"weight": 309,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-authenticator.md",
|
||||
@@ -903,7 +903,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMfaAuthenticator",
|
||||
"group": "mfa",
|
||||
"weight": 52,
|
||||
"weight": 310,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-mfa-authenticator.md",
|
||||
@@ -997,7 +997,7 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"\/account\/mfa\/challenge": {
|
||||
"\/account\/mfa\/challenges": {
|
||||
"post": {
|
||||
"summary": "Create MFA challenge",
|
||||
"operationId": "accountCreateMfaChallenge",
|
||||
@@ -1023,7 +1023,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 53,
|
||||
"weight": 314,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-challenge.md",
|
||||
@@ -1154,7 +1154,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaChallenge",
|
||||
"group": "mfa",
|
||||
"weight": 54,
|
||||
"weight": 315,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-challenge.md",
|
||||
@@ -1290,7 +1290,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMfaFactors",
|
||||
"group": "mfa",
|
||||
"weight": 46,
|
||||
"weight": 307,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/list-mfa-factors.md",
|
||||
@@ -1387,7 +1387,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 51,
|
||||
"weight": 313,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/get-mfa-recovery-codes.md",
|
||||
@@ -1484,7 +1484,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 49,
|
||||
"weight": 311,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-mfa-recovery-codes.md",
|
||||
@@ -1581,7 +1581,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMfaRecoveryCodes",
|
||||
"group": "mfa",
|
||||
"weight": 50,
|
||||
"weight": 312,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-mfa-recovery-codes.md",
|
||||
@@ -3033,7 +3033,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createPushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 55,
|
||||
"weight": 45,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/create-push-target.md",
|
||||
@@ -3117,7 +3117,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 56,
|
||||
"weight": 46,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/update-push-target.md",
|
||||
@@ -3189,7 +3189,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deletePushTarget",
|
||||
"group": "pushTargets",
|
||||
"weight": 57,
|
||||
"weight": 47,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "account\/delete-push-target.md",
|
||||
@@ -4030,7 +4030,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getBrowser",
|
||||
"group": null,
|
||||
"weight": 61,
|
||||
"weight": 51,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-browser.md",
|
||||
@@ -4154,7 +4154,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getCreditCard",
|
||||
"group": null,
|
||||
"weight": 60,
|
||||
"weight": 50,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-credit-card.md",
|
||||
@@ -4284,7 +4284,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFavicon",
|
||||
"group": null,
|
||||
"weight": 64,
|
||||
"weight": 54,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-favicon.md",
|
||||
@@ -4346,7 +4346,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFlag",
|
||||
"group": null,
|
||||
"weight": 62,
|
||||
"weight": 52,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-flag.md",
|
||||
@@ -4832,7 +4832,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getImage",
|
||||
"group": null,
|
||||
"weight": 63,
|
||||
"weight": 53,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-image.md",
|
||||
@@ -4914,7 +4914,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getInitials",
|
||||
"group": null,
|
||||
"weight": 66,
|
||||
"weight": 56,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-initials.md",
|
||||
@@ -5004,7 +5004,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getQR",
|
||||
"group": null,
|
||||
"weight": 65,
|
||||
"weight": 55,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-qr.md",
|
||||
@@ -5094,7 +5094,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getScreenshot",
|
||||
"group": null,
|
||||
"weight": 67,
|
||||
"weight": 57,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "avatars\/get-screenshot.md",
|
||||
@@ -5135,7 +5135,7 @@
|
||||
"required": false,
|
||||
"type": "object",
|
||||
"default": [],
|
||||
"x-example": "{}",
|
||||
"x-example": "{\"Authorization\":\"Bearer token123\",\"X-Custom-Header\":\"value\"}",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
@@ -5144,7 +5144,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1920",
|
||||
"default": 1280,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5154,7 +5154,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 1,
|
||||
"x-example": "1080",
|
||||
"default": 720,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5164,7 +5164,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0.1,
|
||||
"x-example": "2",
|
||||
"default": 1,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5173,7 +5173,7 @@
|
||||
"description": "Browser theme. Pass \"light\" or \"dark\". Defaults to \"light\".",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "light",
|
||||
"x-example": "dark",
|
||||
"enum": [
|
||||
"light",
|
||||
"dark"
|
||||
@@ -5188,7 +5188,7 @@
|
||||
"description": "Custom user agent string. Defaults to browser default.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "<USER_AGENT>",
|
||||
"x-example": "Mozilla\/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit\/605.1.15",
|
||||
"default": "",
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5197,7 +5197,7 @@
|
||||
"description": "Capture full page scroll. Pass 0 for viewport only, or 1 for full page. Defaults to 0.",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5206,7 +5206,7 @@
|
||||
"description": "Browser locale (e.g., \"en-US\", \"fr-FR\"). Defaults to browser default.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "<LOCALE>",
|
||||
"x-example": "en-US",
|
||||
"default": "",
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5215,7 +5215,7 @@
|
||||
"description": "IANA timezone identifier (e.g., \"America\/New_York\", \"Europe\/London\"). Defaults to browser default.",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "africa\/abidjan",
|
||||
"x-example": "america\/new_york",
|
||||
"enum": [
|
||||
"africa\/abidjan",
|
||||
"africa\/accra",
|
||||
@@ -5648,7 +5648,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -90,
|
||||
"x-example": "37.7749",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5658,7 +5658,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": -180,
|
||||
"x-example": "-122.4194",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5668,7 +5668,7 @@
|
||||
"required": false,
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"x-example": 0,
|
||||
"x-example": "100",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5677,7 +5677,7 @@
|
||||
"description": "Enable touch support. Pass 0 for no touch, or 1 for touch enabled. Defaults to 0.",
|
||||
"required": false,
|
||||
"type": "boolean",
|
||||
"x-example": false,
|
||||
"x-example": "true",
|
||||
"default": false,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5688,8 +5688,33 @@
|
||||
"type": "array",
|
||||
"collectionFormat": "multi",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"geolocation",
|
||||
"camera",
|
||||
"microphone",
|
||||
"notifications",
|
||||
"midi",
|
||||
"push",
|
||||
"clipboard-read",
|
||||
"clipboard-write",
|
||||
"payment-handler",
|
||||
"usb",
|
||||
"bluetooth",
|
||||
"accelerometer",
|
||||
"gyroscope",
|
||||
"magnetometer",
|
||||
"ambient-light-sensor",
|
||||
"background-sync",
|
||||
"persistent-storage",
|
||||
"screen-wake-lock",
|
||||
"web-share",
|
||||
"xr-spatial-tracking"
|
||||
],
|
||||
"x-enum-name": "BrowserPermission",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"x-example": "[\"geolocation\",\"notifications\"]",
|
||||
"default": [],
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5699,7 +5724,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "3",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5709,7 +5734,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "800",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5719,7 +5744,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": 0,
|
||||
"x-example": "600",
|
||||
"default": 0,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5729,7 +5754,7 @@
|
||||
"required": false,
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"x-example": -1,
|
||||
"x-example": "85",
|
||||
"default": -1,
|
||||
"in": "query"
|
||||
},
|
||||
@@ -5738,7 +5763,7 @@
|
||||
"description": "Output format type (jpeg, jpg, png, gif and webp).",
|
||||
"required": false,
|
||||
"type": "string",
|
||||
"x-example": "jpg",
|
||||
"x-example": "jpeg",
|
||||
"enum": [
|
||||
"jpg",
|
||||
"jpeg",
|
||||
@@ -7420,7 +7445,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "query",
|
||||
"group": "graphql",
|
||||
"weight": 251,
|
||||
"weight": 241,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/query.md",
|
||||
@@ -7493,7 +7518,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "mutation",
|
||||
"group": "graphql",
|
||||
"weight": 250,
|
||||
"weight": 240,
|
||||
"cookies": false,
|
||||
"type": "graphql",
|
||||
"demo": "graphql\/mutation.md",
|
||||
@@ -7564,7 +7589,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": null,
|
||||
"weight": 71,
|
||||
"weight": 61,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/get.md",
|
||||
@@ -7615,7 +7640,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCodes",
|
||||
"group": null,
|
||||
"weight": 72,
|
||||
"weight": 62,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-codes.md",
|
||||
@@ -7666,7 +7691,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listContinents",
|
||||
"group": null,
|
||||
"weight": 76,
|
||||
"weight": 66,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-continents.md",
|
||||
@@ -7717,7 +7742,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountries",
|
||||
"group": null,
|
||||
"weight": 73,
|
||||
"weight": 63,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries.md",
|
||||
@@ -7768,7 +7793,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesEU",
|
||||
"group": null,
|
||||
"weight": 74,
|
||||
"weight": 64,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-eu.md",
|
||||
@@ -7819,7 +7844,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCountriesPhones",
|
||||
"group": null,
|
||||
"weight": 75,
|
||||
"weight": 65,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-countries-phones.md",
|
||||
@@ -7870,7 +7895,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listCurrencies",
|
||||
"group": null,
|
||||
"weight": 77,
|
||||
"weight": 67,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-currencies.md",
|
||||
@@ -7921,7 +7946,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listLanguages",
|
||||
"group": null,
|
||||
"weight": 78,
|
||||
"weight": 68,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "locale\/list-languages.md",
|
||||
@@ -7974,7 +7999,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 300,
|
||||
"weight": 290,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/create-subscriber.md",
|
||||
@@ -8058,7 +8083,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteSubscriber",
|
||||
"group": "subscribers",
|
||||
"weight": 304,
|
||||
"weight": 294,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "messaging\/delete-subscriber.md",
|
||||
@@ -8128,7 +8153,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listFiles",
|
||||
"group": "files",
|
||||
"weight": 161,
|
||||
"weight": 151,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/list-files.md",
|
||||
@@ -8219,7 +8244,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createFile",
|
||||
"group": "files",
|
||||
"weight": 160,
|
||||
"weight": 150,
|
||||
"cookies": false,
|
||||
"type": "upload",
|
||||
"demo": "storage\/create-file.md",
|
||||
@@ -8308,7 +8333,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFile",
|
||||
"group": "files",
|
||||
"weight": 162,
|
||||
"weight": 152,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/get-file.md",
|
||||
@@ -8377,7 +8402,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateFile",
|
||||
"group": "files",
|
||||
"weight": 167,
|
||||
"weight": 157,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/update-file.md",
|
||||
@@ -8467,7 +8492,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteFile",
|
||||
"group": "files",
|
||||
"weight": 168,
|
||||
"weight": 158,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "storage\/delete-file.md",
|
||||
@@ -8536,7 +8561,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileDownload",
|
||||
"group": "files",
|
||||
"weight": 164,
|
||||
"weight": 154,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-download.md",
|
||||
@@ -8614,7 +8639,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFilePreview",
|
||||
"group": "files",
|
||||
"weight": 163,
|
||||
"weight": 153,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-preview.md",
|
||||
@@ -8820,7 +8845,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getFileView",
|
||||
"group": "files",
|
||||
"weight": 165,
|
||||
"weight": 155,
|
||||
"cookies": false,
|
||||
"type": "location",
|
||||
"demo": "storage\/get-file-view.md",
|
||||
@@ -10265,7 +10290,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "list",
|
||||
"group": "teams",
|
||||
"weight": 172,
|
||||
"weight": 162,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list.md",
|
||||
@@ -10348,7 +10373,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "create",
|
||||
"group": "teams",
|
||||
"weight": 171,
|
||||
"weight": 161,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create.md",
|
||||
@@ -10437,7 +10462,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "get",
|
||||
"group": "teams",
|
||||
"weight": 173,
|
||||
"weight": 163,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get.md",
|
||||
@@ -10498,7 +10523,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateName",
|
||||
"group": "teams",
|
||||
"weight": 175,
|
||||
"weight": 165,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-name.md",
|
||||
@@ -10572,7 +10597,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "delete",
|
||||
"group": "teams",
|
||||
"weight": 177,
|
||||
"weight": 167,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete.md",
|
||||
@@ -10633,7 +10658,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "listMemberships",
|
||||
"group": "memberships",
|
||||
"weight": 179,
|
||||
"weight": 169,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/list-memberships.md",
|
||||
@@ -10724,7 +10749,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "createMembership",
|
||||
"group": "memberships",
|
||||
"weight": 178,
|
||||
"weight": 168,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/create-membership.md",
|
||||
@@ -10788,7 +10813,14 @@
|
||||
"default": null,
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
@@ -10836,7 +10868,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getMembership",
|
||||
"group": "memberships",
|
||||
"weight": 180,
|
||||
"weight": 170,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-membership.md",
|
||||
@@ -10905,7 +10937,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembership",
|
||||
"group": "memberships",
|
||||
"weight": 181,
|
||||
"weight": 171,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership.md",
|
||||
@@ -10959,7 +10991,14 @@
|
||||
"default": null,
|
||||
"x-example": null,
|
||||
"items": {
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"admin",
|
||||
"developer",
|
||||
"owner"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-keys": []
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -10990,7 +11029,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "deleteMembership",
|
||||
"group": "memberships",
|
||||
"weight": 183,
|
||||
"weight": 173,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/delete-membership.md",
|
||||
@@ -11061,7 +11100,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updateMembershipStatus",
|
||||
"group": "memberships",
|
||||
"weight": 182,
|
||||
"weight": 172,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-membership-status.md",
|
||||
@@ -11155,7 +11194,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "getPrefs",
|
||||
"group": "teams",
|
||||
"weight": 174,
|
||||
"weight": 164,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/get-prefs.md",
|
||||
@@ -11216,7 +11255,7 @@
|
||||
"x-appwrite": {
|
||||
"method": "updatePrefs",
|
||||
"group": "teams",
|
||||
"weight": 176,
|
||||
"weight": 166,
|
||||
"cookies": false,
|
||||
"type": "",
|
||||
"demo": "teams\/update-prefs.md",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,43 +1,12 @@
|
||||
<?php
|
||||
|
||||
// TODO: Remove, replace with runtimes.php directly
|
||||
// Used in function templates and site frameworks
|
||||
use Utopia\Config\Config;
|
||||
|
||||
return [
|
||||
'NODE' => [
|
||||
'name' => 'node',
|
||||
'versions' => ['22', '21.0', '20.0', '19.0', '18.0', '16.0', '14.5']
|
||||
],
|
||||
'PYTHON' => [
|
||||
'name' => 'python',
|
||||
'versions' => ['3.12', '3.11', '3.10', '3.9', '3.8']
|
||||
],
|
||||
'DART' => [
|
||||
'name' => 'dart',
|
||||
'versions' => ['3.9', '3.8', '3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
|
||||
],
|
||||
'GO' => [
|
||||
'name' => 'go',
|
||||
'versions' => ['1.23']
|
||||
],
|
||||
'PHP' => [
|
||||
'name' => 'php',
|
||||
'versions' => ['8.3', '8.2', '8.1', '8.0']
|
||||
],
|
||||
'DENO' => [
|
||||
'name' => 'deno',
|
||||
'versions' => ['2.0', '1.46', '1.40', '1.35', '1.24', '1.21']
|
||||
],
|
||||
'BUN' => [
|
||||
'name' => 'bun',
|
||||
'versions' => ['1.1', '1.0']
|
||||
],
|
||||
'RUBY' => [
|
||||
'name' => 'ruby',
|
||||
'versions' => ['3.3', '3.2', '3.1', '3.0']
|
||||
],
|
||||
'FLUTTER' => [
|
||||
'name' => 'flutter',
|
||||
'versions' => ['3.35', '3.32', '3.24']
|
||||
],
|
||||
];
|
||||
$runtimes = Config::getParam('runtimes');
|
||||
|
||||
$mappedRuntimes = \array_reduce($runtimes, function ($acc, $runtime) {
|
||||
$acc[strtoupper($runtime['key'])][] = $runtime['key'] . '-' . $runtime['version'];
|
||||
return $acc;
|
||||
}, []);
|
||||
|
||||
return $mappedRuntimes;
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\System\System;
|
||||
|
||||
$templateRuntimes = Config::getParam('template-runtimes');
|
||||
$allowList = \array_map('trim', \explode(',', System::getEnv('_APP_FUNCTIONS_RUNTIMES', '')));
|
||||
|
||||
function getRuntimes($runtime, $commands, $entrypoint, $providerRootDirectory, $versionsDenyList = [])
|
||||
function getRuntimes($runtimes, $commands, $entrypoint, $providerRootDirectory, $allowList)
|
||||
{
|
||||
return array_map(function ($version) use ($runtime, $commands, $entrypoint, $providerRootDirectory) {
|
||||
return array_map(function ($runtime) use ($commands, $entrypoint, $providerRootDirectory) {
|
||||
return [
|
||||
'name' => $runtime['name'] . '-' . $version,
|
||||
'name' => $runtime,
|
||||
'commands' => $commands,
|
||||
'entrypoint' => $entrypoint,
|
||||
'providerRootDirectory' => $providerRootDirectory
|
||||
];
|
||||
}, array_filter($runtime['versions'], function ($version) use ($versionsDenyList) {
|
||||
return !in_array($version, $versionsDenyList);
|
||||
}, array_filter($runtimes, function ($runtime) use ($allowList) {
|
||||
return in_array($runtime, $allowList);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -32,24 +34,26 @@ return [
|
||||
'timeout' => 15,
|
||||
'useCases' => ['starter'],
|
||||
'runtimes' => [
|
||||
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/starter'),
|
||||
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/starter', $allowList),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/starter'
|
||||
'python/starter',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/starter'),
|
||||
...getRuntimes($templateRuntimes['GO'], '', 'main.go', 'go/starter'),
|
||||
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/starter', $allowList),
|
||||
...getRuntimes($templateRuntimes['GO'], '', 'main.go', 'go/starter', $allowList),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PHP'],
|
||||
'composer install',
|
||||
'src/index.php',
|
||||
'php/starter'
|
||||
'php/starter',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes($templateRuntimes['DENO'], 'deno cache src/main.ts', 'src/main.ts', 'deno/starter'),
|
||||
...getRuntimes($templateRuntimes['BUN'], 'bun install', 'src/main.ts', 'bun/starter'),
|
||||
...getRuntimes($templateRuntimes['RUBY'], 'bundle install', 'lib/main.rb', 'ruby/starter'),
|
||||
...getRuntimes($templateRuntimes['DENO'], 'deno cache src/main.ts', 'src/main.ts', 'deno/starter', $allowList),
|
||||
...getRuntimes($templateRuntimes['BUN'], 'bun install', 'src/main.ts', 'bun/starter', $allowList),
|
||||
...getRuntimes($templateRuntimes['RUBY'], 'bundle install', 'lib/main.rb', 'ruby/starter', $allowList),
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/starter">file</a>.',
|
||||
'vcsProvider' => 'github',
|
||||
@@ -75,7 +79,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/query-upstash-vector'
|
||||
'node/query-upstash-vector',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/query-upstash-vector">file</a>.',
|
||||
@@ -120,7 +125,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/query-redis-labs'
|
||||
'node/query-redis-labs',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/query-redis-labs">file</a>.',
|
||||
@@ -164,7 +170,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/query-neo4j-auradb'
|
||||
'node/query-neo4j-auradb',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/query-neo4j-auradb">file</a>.',
|
||||
@@ -217,7 +224,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/query-mongo-atlas'
|
||||
'node/query-mongo-atlas',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/query-mongo-atlas">file</a>.',
|
||||
@@ -255,7 +263,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/query-neon-postgres'
|
||||
'node/query-neon-postgres',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/query-neon-postgres">file</a>.',
|
||||
@@ -323,25 +332,29 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/prompt-chatgpt'
|
||||
'node/prompt-chatgpt',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/prompt_chatgpt'
|
||||
'python/prompt_chatgpt',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PHP'],
|
||||
'composer install',
|
||||
'src/index.php',
|
||||
'php/prompt-chatgpt'
|
||||
'php/prompt-chatgpt',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['DART'],
|
||||
'dart pub get',
|
||||
'lib/main.dart',
|
||||
'dart/prompt_chatgpt'
|
||||
'dart/prompt_chatgpt',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/prompt-chatgpt">file</a>.',
|
||||
@@ -385,19 +398,22 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install && npm run setup',
|
||||
'src/main.js',
|
||||
'node/discord-command-bot'
|
||||
'node/discord-command-bot',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt && python src/setup.py',
|
||||
'src/main.py',
|
||||
'python/discord_command_bot'
|
||||
'python/discord_command_bot',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['GO'],
|
||||
'',
|
||||
'main.go',
|
||||
'go/discord-command-bot'
|
||||
'go/discord-command-bot',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/discord-command-bot">file</a>.',
|
||||
@@ -449,7 +465,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/analyze-with-perspectiveapi'
|
||||
'node/analyze-with-perspectiveapi',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/analyze-with-perspectiveapi">file</a>.',
|
||||
@@ -486,19 +503,22 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/censor-with-redact'
|
||||
'node/censor-with-redact',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/censor_with_redact'
|
||||
'python/censor_with_redact',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['DART'],
|
||||
'dart pub get',
|
||||
'lib/main.dart',
|
||||
'dart/censor_with_redact'
|
||||
'dart/censor_with_redact',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/censor-with-redact">file</a>.',
|
||||
@@ -530,7 +550,7 @@ return [
|
||||
'timeout' => 15,
|
||||
'useCases' => ['utilities'],
|
||||
'runtimes' => [
|
||||
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/generate-pdf')
|
||||
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/generate-pdf', $allowList)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/generate-pdf">file</a>.',
|
||||
'vcsProvider' => 'github',
|
||||
@@ -557,7 +577,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/github-issue-bot'
|
||||
'node/github-issue-bot',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/github-issue-bot">file</a>.',
|
||||
@@ -601,7 +622,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/url-shortener'
|
||||
'node/url-shortener',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/url-shortener">file</a>.',
|
||||
@@ -653,19 +675,22 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/sync-with-algolia'
|
||||
'node/sync-with-algolia',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/sync_with_algolia'
|
||||
'python/sync_with_algolia',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PHP'],
|
||||
'composer install',
|
||||
'src/index.php',
|
||||
'php/sync-with-algolia'
|
||||
'php/sync-with-algolia',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/sync-with-algolia">file</a>.',
|
||||
@@ -735,31 +760,36 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/sync-with-meilisearch'
|
||||
'node/sync-with-meilisearch',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/sync-with-meilisearch'
|
||||
'python/sync-with-meilisearch',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PHP'],
|
||||
'composer install',
|
||||
'src/index.php',
|
||||
'php/sync-with-meilisearch'
|
||||
'php/sync-with-meilisearch',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['BUN'],
|
||||
'bun install',
|
||||
'src/main.ts',
|
||||
'bun/sync-with-meilisearch'
|
||||
'bun/sync-with-meilisearch',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['RUBY'],
|
||||
'bundle install',
|
||||
'lib/main.rb',
|
||||
'ruby/sync-with-meilisearch'
|
||||
'ruby/sync-with-meilisearch',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/sync-with-meilisearch">file</a>.',
|
||||
@@ -829,37 +859,43 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/whatsapp-with-vonage'
|
||||
'node/whatsapp-with-vonage',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/whatsapp_with_vonage'
|
||||
'python/whatsapp_with_vonage',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['DART'],
|
||||
'dart pub get',
|
||||
'lib/main.dart',
|
||||
'dart/whatsapp-with-vonage'
|
||||
'dart/whatsapp-with-vonage',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PHP'],
|
||||
'composer install',
|
||||
'src/index.php',
|
||||
'php/whatsapp-with-vonage'
|
||||
'php/whatsapp-with-vonage',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['BUN'],
|
||||
'bun install',
|
||||
'src/main.ts',
|
||||
'bun/whatsapp-with-vonage'
|
||||
'bun/whatsapp-with-vonage',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['RUBY'],
|
||||
'bundle install',
|
||||
'lib/main.rb',
|
||||
'ruby/whatsapp-with-vonage'
|
||||
'ruby/whatsapp-with-vonage',
|
||||
$allowList
|
||||
),
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/whatsapp-with-vonage">file</a>.',
|
||||
@@ -916,7 +952,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/push-notification-with-fcm'
|
||||
'node/push-notification-with-fcm',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/push-notification-with-fcm">file</a>.',
|
||||
@@ -973,19 +1010,22 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/email-contact-form'
|
||||
'node/email-contact-form',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PYTHON'],
|
||||
'pip install -r requirements.txt',
|
||||
'src/main.py',
|
||||
'python/email_contact_form'
|
||||
'python/email_contact_form',
|
||||
$allowList
|
||||
),
|
||||
...getRuntimes(
|
||||
$templateRuntimes['PHP'],
|
||||
'composer install',
|
||||
'src/index.php',
|
||||
'php/email-contact-form'
|
||||
'php/email-contact-form',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/email-contact-form">file</a>.',
|
||||
@@ -1057,7 +1097,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/subscriptions-with-stripe'
|
||||
'node/subscriptions-with-stripe',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/subscriptions-with-stripe">file</a>.',
|
||||
@@ -1099,7 +1140,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/payments-with-stripe'
|
||||
'node/payments-with-stripe',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/payments-with-stripe">file</a>.',
|
||||
@@ -1157,7 +1199,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/text-generation-with-huggingface'
|
||||
'node/text-generation-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/text-generation-with-huggingface">file</a>.',
|
||||
@@ -1192,7 +1235,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/language-translation-with-huggingface'
|
||||
'node/language-translation-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/language-translation-with-huggingface">file</a>.',
|
||||
@@ -1227,7 +1271,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install && npm run setup',
|
||||
'src/main.js',
|
||||
'node/image-classification-with-huggingface'
|
||||
'node/image-classification-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/image-classification-with-huggingface">file</a>.',
|
||||
@@ -1286,7 +1331,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install && npm run setup',
|
||||
'src/main.js',
|
||||
'node/object-detection-with-huggingface'
|
||||
'node/object-detection-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/object-detection-with-huggingface">file</a>.',
|
||||
@@ -1345,7 +1391,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install && npm run setup',
|
||||
'src/main.js',
|
||||
'node/speech-recognition-with-huggingface'
|
||||
'node/speech-recognition-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/speech-recognition-with-huggingface">file</a>.',
|
||||
@@ -1407,7 +1454,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install && npm run setup',
|
||||
'src/main.js',
|
||||
'node/text-to-speech-with-huggingface'
|
||||
'node/text-to-speech-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/text-to-speech-with-huggingface">file</a>.',
|
||||
@@ -1466,7 +1514,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/generate-with-replicate'
|
||||
'node/generate-with-replicate',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/generate-with-replicate">file</a>.',
|
||||
@@ -1502,7 +1551,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/generate-with-together-ai'
|
||||
'node/generate-with-together-ai',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/generate-with-together-ai">file</a>.',
|
||||
@@ -1545,7 +1595,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/chat-with-perplexity-ai'
|
||||
'node/chat-with-perplexity-ai',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/chat-with-perplexity-ai">file</a>.',
|
||||
@@ -1587,7 +1638,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/generate-with-replicate'
|
||||
'node/generate-with-replicate',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/generate-with-replicate">file</a>.',
|
||||
@@ -1623,7 +1675,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/sync-with-pinecone'
|
||||
'node/sync-with-pinecone',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/sync-with-pinecone">file</a>.',
|
||||
@@ -1687,7 +1740,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/rag-with-langchain'
|
||||
'node/rag-with-langchain',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/rag-with-langchain">file</a>.',
|
||||
@@ -1751,7 +1805,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/speak-with-elevenlabs'
|
||||
'node/speak-with-elevenlabs',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/speak-with-elevenlabs">file</a>.',
|
||||
@@ -1807,7 +1862,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/speak-with-lmnt'
|
||||
'node/speak-with-lmnt',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/speak-with-lmnt">file</a>.',
|
||||
@@ -1849,7 +1905,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/chat-with-anyscale'
|
||||
'node/chat-with-anyscale',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/chat-with-anyscale">file</a>.',
|
||||
@@ -1891,7 +1948,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install && npm run setup',
|
||||
'src/main.js',
|
||||
'node/music-generation-with-huggingface'
|
||||
'node/music-generation-with-huggingface',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/music-generation-with-huggingface">file</a>.',
|
||||
@@ -1934,7 +1992,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/generate-with-fal-ai'
|
||||
'node/generate-with-fal-ai',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/generate-with-fal-ai">file</a>.',
|
||||
@@ -1970,7 +2029,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/subscriptions-with-lemon-squeezy'
|
||||
'node/subscriptions-with-lemon-squeezy',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/subscriptions-with-lemon-squeezy">file</a>.',
|
||||
@@ -2026,7 +2086,8 @@ return [
|
||||
$templateRuntimes['NODE'],
|
||||
'npm install',
|
||||
'src/main.js',
|
||||
'node/payments-with-lemon-squeezy'
|
||||
'node/payments-with-lemon-squeezy',
|
||||
$allowList
|
||||
)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/payments-with-lemon-squeezy">file</a>.',
|
||||
@@ -2094,7 +2155,7 @@ return [
|
||||
'timeout' => 15,
|
||||
'useCases' => ['auth'],
|
||||
'runtimes' => [
|
||||
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/sign_in_with_apple')
|
||||
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/sign_in_with_apple', $allowList)
|
||||
],
|
||||
'instructions' => 'For documentation and instructions, check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/dart/sign_in_with_apple">file</a>.',
|
||||
'vcsProvider' => 'github',
|
||||
|
||||
@@ -362,7 +362,7 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => '_APP_DB_ADAPTER',
|
||||
'description' => 'To switch between mariadb and mongoDB',
|
||||
'description' => 'Which database engine to use. Possible options are "mariadb" or "mongodb"',
|
||||
'introduction' => '1.8.0',
|
||||
'default' => 'mongoDB',
|
||||
'required' => true,
|
||||
|
||||
@@ -888,7 +888,11 @@ App::patch('/v1/account/sessions/:sessionId')
|
||||
// Refresh OAuth access token
|
||||
$provider = $session->getAttribute('provider', '');
|
||||
$refreshToken = $session->getAttribute('providerRefreshToken', '');
|
||||
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
|
||||
$oAuthProviders = Config::getParam('oAuthProviders');
|
||||
$className = $oAuthProviders[$provider]['class'];
|
||||
if (!\class_exists($className)) {
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
|
||||
if (!empty($provider) && \class_exists($className)) {
|
||||
$appId = $project->getAttribute('oAuthProviders', [])[$provider . 'Appid'] ?? '';
|
||||
@@ -1466,8 +1470,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
$appSecret = $project->getAttribute('oAuthProviders', [])[$provider . 'Secret'] ?? '{}';
|
||||
$providerEnabled = $project->getAttribute('oAuthProviders', [])[$provider . 'Enabled'] ?? false;
|
||||
|
||||
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
|
||||
|
||||
$oAuthProviders = Config::getParam('oAuthProviders');
|
||||
$className = $oAuthProviders[$provider]['class'];
|
||||
if (!\class_exists($className)) {
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
@@ -1981,8 +1985,8 @@ App::get('/v1/account/tokens/oauth2/:provider')
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_DISABLED, 'This provider is disabled. Please configure the provider app ID and app secret key from your ' . APP_NAME . ' console to continue.');
|
||||
}
|
||||
|
||||
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
|
||||
|
||||
$oAuthProviders = Config::getParam('oAuthProviders');
|
||||
$className = $oAuthProviders[$provider]['class'];
|
||||
if (!\class_exists($className)) {
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@@ -96,8 +96,8 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro
|
||||
$appId = $project->getAttribute('oAuthProviders', [])[$provider . 'Appid'] ?? '';
|
||||
$appSecret = $project->getAttribute('oAuthProviders', [])[$provider . 'Secret'] ?? '{}';
|
||||
|
||||
$className = 'Appwrite\\Auth\\OAuth2\\' . \ucfirst($provider);
|
||||
|
||||
$oAuthProviders = Config::getParam('oAuthProviders');
|
||||
$className = $oAuthProviders[$provider]['class'];
|
||||
if (!\class_exists($className)) {
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
@@ -662,26 +662,26 @@ App::get('/v1/avatars/screenshots')
|
||||
],
|
||||
contentType: ContentType::IMAGE_PNG
|
||||
))
|
||||
->param('url', '', new URL(['http', 'https']), 'Website URL which you want to capture.')
|
||||
->param('headers', [], new Assoc(), 'HTTP headers to send with the browser request. Defaults to empty.', true)
|
||||
->param('viewportWidth', 1280, new Range(1, 1920), 'Browser viewport width. Pass an integer between 1 to 1920. Defaults to 1280.', true)
|
||||
->param('viewportHeight', 720, new Range(1, 1080), 'Browser viewport height. Pass an integer between 1 to 1080. Defaults to 720.', true)
|
||||
->param('scale', 1, new Range(0.1, 3, Range::TYPE_FLOAT), 'Browser scale factor. Pass a number between 0.1 to 3. Defaults to 1.', true)
|
||||
->param('theme', 'light', new WhiteList(['light', 'dark']), 'Browser theme. Pass "light" or "dark". Defaults to "light".', true)
|
||||
->param('userAgent', '', new Text(512), 'Custom user agent string. Defaults to browser default.', true)
|
||||
->param('fullpage', false, new Boolean(true), 'Capture full page scroll. Pass 0 for viewport only, or 1 for full page. Defaults to 0.', true)
|
||||
->param('locale', '', new Text(10), 'Browser locale (e.g., "en-US", "fr-FR"). Defaults to browser default.', true)
|
||||
->param('timezone', '', new WhiteList(timezone_identifiers_list()), 'IANA timezone identifier (e.g., "America/New_York", "Europe/London"). Defaults to browser default.', true)
|
||||
->param('latitude', 0, new Range(-90, 90, Range::TYPE_FLOAT), 'Geolocation latitude. Pass a number between -90 to 90. Defaults to 0.', true)
|
||||
->param('longitude', 0, new Range(-180, 180, Range::TYPE_FLOAT), 'Geolocation longitude. Pass a number between -180 to 180. Defaults to 0.', true)
|
||||
->param('accuracy', 0, new Range(0, 100000, Range::TYPE_FLOAT), 'Geolocation accuracy in meters. Pass a number between 0 to 100000. Defaults to 0.', true)
|
||||
->param('touch', false, new Boolean(true), 'Enable touch support. Pass 0 for no touch, or 1 for touch enabled. Defaults to 0.', true)
|
||||
->param('permissions', [], new ArrayList(new WhiteList(['geolocation', 'camera', 'microphone', 'notifications', 'midi', 'push', 'clipboard-read', 'clipboard-write', 'payment-handler', 'usb', 'bluetooth', 'accelerometer', 'gyroscope', 'magnetometer', 'ambient-light-sensor', 'background-sync', 'persistent-storage', 'screen-wake-lock', 'web-share', 'xr-spatial-tracking'])), 'Browser permissions to grant. Pass an array of permission names like ["geolocation", "camera", "microphone"]. Defaults to empty.', true)
|
||||
->param('sleep', 0, new Range(0, 10), 'Wait time in seconds before taking the screenshot. Pass an integer between 0 to 10. Defaults to 0.', true)
|
||||
->param('width', 0, new Range(0, 2000), 'Output image width. Pass 0 to use original width, or an integer between 1 to 2000. Defaults to 0 (original width).', true)
|
||||
->param('height', 0, new Range(0, 2000), 'Output image height. Pass 0 to use original height, or an integer between 1 to 2000. Defaults to 0 (original height).', true)
|
||||
->param('quality', -1, new Range(-1, 100), 'Screenshot quality. Pass an integer between 0 to 100. Defaults to keep existing image quality.', true)
|
||||
->param('output', '', new WhiteList(\array_keys(Config::getParam('storage-outputs')), true), 'Output format type (jpeg, jpg, png, gif and webp).', true)
|
||||
->param('url', '', new URL(['http', 'https']), 'Website URL which you want to capture.', example: 'https://example.com')
|
||||
->param('headers', [], new Assoc(), 'HTTP headers to send with the browser request. Defaults to empty.', true, example: '{"Authorization":"Bearer token123","X-Custom-Header":"value"}')
|
||||
->param('viewportWidth', 1280, new Range(1, 1920), 'Browser viewport width. Pass an integer between 1 to 1920. Defaults to 1280.', true, example: '1920')
|
||||
->param('viewportHeight', 720, new Range(1, 1080), 'Browser viewport height. Pass an integer between 1 to 1080. Defaults to 720.', true, example: '1080')
|
||||
->param('scale', 1, new Range(0.1, 3, Range::TYPE_FLOAT), 'Browser scale factor. Pass a number between 0.1 to 3. Defaults to 1.', true, example: '2')
|
||||
->param('theme', 'light', new WhiteList(['light', 'dark']), 'Browser theme. Pass "light" or "dark". Defaults to "light".', true, example: 'dark')
|
||||
->param('userAgent', '', new Text(512), 'Custom user agent string. Defaults to browser default.', true, example: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15')
|
||||
->param('fullpage', false, new Boolean(true), 'Capture full page scroll. Pass 0 for viewport only, or 1 for full page. Defaults to 0.', true, example: 'true')
|
||||
->param('locale', '', new Text(10), 'Browser locale (e.g., "en-US", "fr-FR"). Defaults to browser default.', true, example: 'en-US')
|
||||
->param('timezone', '', new WhiteList(timezone_identifiers_list()), 'IANA timezone identifier (e.g., "America/New_York", "Europe/London"). Defaults to browser default.', true, example: 'america/new_york')
|
||||
->param('latitude', 0, new Range(-90, 90, Range::TYPE_FLOAT), 'Geolocation latitude. Pass a number between -90 to 90. Defaults to 0.', true, example: '37.7749')
|
||||
->param('longitude', 0, new Range(-180, 180, Range::TYPE_FLOAT), 'Geolocation longitude. Pass a number between -180 to 180. Defaults to 0.', true, example: '-122.4194')
|
||||
->param('accuracy', 0, new Range(0, 100000, Range::TYPE_FLOAT), 'Geolocation accuracy in meters. Pass a number between 0 to 100000. Defaults to 0.', true, example: '100')
|
||||
->param('touch', false, new Boolean(true), 'Enable touch support. Pass 0 for no touch, or 1 for touch enabled. Defaults to 0.', true, example: 'true')
|
||||
->param('permissions', [], new ArrayList(new WhiteList(['geolocation', 'camera', 'microphone', 'notifications', 'midi', 'push', 'clipboard-read', 'clipboard-write', 'payment-handler', 'usb', 'bluetooth', 'accelerometer', 'gyroscope', 'magnetometer', 'ambient-light-sensor', 'background-sync', 'persistent-storage', 'screen-wake-lock', 'web-share', 'xr-spatial-tracking'])), 'Browser permissions to grant. Pass an array of permission names like ["geolocation", "camera", "microphone"]. Defaults to empty.', true, example: '["geolocation","notifications"]')
|
||||
->param('sleep', 0, new Range(0, 10), 'Wait time in seconds before taking the screenshot. Pass an integer between 0 to 10. Defaults to 0.', true, example: '3')
|
||||
->param('width', 0, new Range(0, 2000), 'Output image width. Pass 0 to use original width, or an integer between 1 to 2000. Defaults to 0 (original width).', true, example: '800')
|
||||
->param('height', 0, new Range(0, 2000), 'Output image height. Pass 0 to use original height, or an integer between 1 to 2000. Defaults to 0 (original height).', true, example: '600')
|
||||
->param('quality', -1, new Range(-1, 100), 'Screenshot quality. Pass an integer between 0 to 100. Defaults to keep existing image quality.', true, example: '85')
|
||||
->param('output', '', new WhiteList(\array_keys(Config::getParam('storage-outputs')), true), 'Output format type (jpeg, jpg, png, gif and webp).', true, example: 'jpeg')
|
||||
->inject('response')
|
||||
->inject('queueForStatsUsage')
|
||||
->action(function (string $url, array $headers, int $viewportWidth, int $viewportHeight, float $scale, string $theme, string $userAgent, bool $fullpage, string $locale, string $timezone, float $latitude, float $longitude, float $accuracy, bool $touch, array $permissions, int $sleep, int $width, int $height, int $quality, string $output, Response $response, StatsUsage $queueForStatsUsage) {
|
||||
|
||||
@@ -46,9 +46,9 @@ include_once __DIR__ . '/../shared/api.php';
|
||||
function getDatabaseTransferResourceServices(string $databaseType)
|
||||
{
|
||||
return match($databaseType) {
|
||||
DATABASE_LEGACY_TYPE,
|
||||
DATABASE_TABLESDB_TYPE => Transfer::GROUP_DATABASES_TABLES_DB,
|
||||
DATABASE_VECTORDB_TYPE => Transfer::GROUP_DATABASES_VECTOR_DB
|
||||
DATABASE_TYPE_LEGACY,
|
||||
DATABASE_TYPE_TABLESDB => Transfer::GROUP_DATABASES_TABLES_DB,
|
||||
DATABASE_TYPE_VECTORDB => Transfer::GROUP_DATABASES_VECTOR_DB
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -61,15 +61,20 @@ App::get('/v1/project/usage')
|
||||
METRIC_EXECUTIONS_MB_SECONDS,
|
||||
METRIC_BUILDS_MB_SECONDS,
|
||||
METRIC_DOCUMENTS,
|
||||
METRIC_DOCUMENTS_DOCUMENTSDB,
|
||||
METRIC_DATABASES,
|
||||
METRIC_DATABASES_DOCUMENTSDB,
|
||||
METRIC_USERS,
|
||||
METRIC_BUCKETS,
|
||||
METRIC_FILES_STORAGE,
|
||||
METRIC_DATABASES_STORAGE,
|
||||
METRIC_DATABASES_STORAGE_DOCUMENTSDB,
|
||||
METRIC_DEPLOYMENTS_STORAGE,
|
||||
METRIC_BUILDS_STORAGE,
|
||||
METRIC_DATABASES_OPERATIONS_READS,
|
||||
METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB,
|
||||
METRIC_FILES_IMAGES_TRANSFORMED,
|
||||
METRIC_EMBEDDINGS_TEXT,
|
||||
METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS,
|
||||
@@ -83,10 +88,13 @@ App::get('/v1/project/usage')
|
||||
METRIC_USERS,
|
||||
METRIC_EXECUTIONS,
|
||||
METRIC_DATABASES_STORAGE,
|
||||
METRIC_DATABASES_STORAGE_DOCUMENTSDB,
|
||||
METRIC_EXECUTIONS_MB_SECONDS,
|
||||
METRIC_BUILDS_MB_SECONDS,
|
||||
METRIC_DATABASES_OPERATIONS_READS,
|
||||
METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB,
|
||||
METRIC_FILES_IMAGES_TRANSFORMED,
|
||||
METRIC_EMBEDDINGS_TEXT,
|
||||
METRIC_EMBEDDINGS_TEXT_TOTAL_TOKENS,
|
||||
@@ -364,8 +372,11 @@ App::get('/v1/project/usage')
|
||||
'buildsMbSecondsTotal' => $total[METRIC_BUILDS_MB_SECONDS],
|
||||
'documentsTotal' => $total[METRIC_DOCUMENTS],
|
||||
'rowsTotal' => $total[METRIC_DOCUMENTS],
|
||||
'documentsdbDocumentsTotal' => $total[METRIC_DOCUMENTS_DOCUMENTSDB],
|
||||
'databasesTotal' => $total[METRIC_DATABASES],
|
||||
'documentsdbTotal' => $total[METRIC_DATABASES_DOCUMENTSDB],
|
||||
'databasesStorageTotal' => $total[METRIC_DATABASES_STORAGE],
|
||||
'documentsdbDatabasesStorageTotal' => $total[METRIC_DATABASES_STORAGE_DOCUMENTSDB],
|
||||
'usersTotal' => $total[METRIC_USERS],
|
||||
'bucketsTotal' => $total[METRIC_BUCKETS],
|
||||
'filesStorageTotal' => $total[METRIC_FILES_STORAGE],
|
||||
@@ -374,10 +385,15 @@ App::get('/v1/project/usage')
|
||||
'deploymentsStorageTotal' => $total[METRIC_DEPLOYMENTS_STORAGE],
|
||||
'databasesReadsTotal' => $total[METRIC_DATABASES_OPERATIONS_READS],
|
||||
'databasesWritesTotal' => $total[METRIC_DATABASES_OPERATIONS_WRITES],
|
||||
'documentsdbDatabasesReadsTotal' => $total[METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB],
|
||||
'documentsdbDatabasesWritesTotal' => $total[METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB],
|
||||
'executionsBreakdown' => $executionsBreakdown,
|
||||
'bucketsBreakdown' => $bucketsBreakdown,
|
||||
'databasesReads' => $usage[METRIC_DATABASES_OPERATIONS_READS],
|
||||
'databasesWrites' => $usage[METRIC_DATABASES_OPERATIONS_WRITES],
|
||||
'documentsdbDatabasesReads' => $usage[METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB],
|
||||
'documentsdbDatabasesWrites' => $usage[METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB],
|
||||
'documentsdbDatabasesStorage' => $usage[METRIC_DATABASES_STORAGE_DOCUMENTSDB],
|
||||
'databasesStorageBreakdown' => $databasesStorageBreakdown,
|
||||
'executionsMbSecondsBreakdown' => $executionsMbSecondsBreakdown,
|
||||
'buildsMbSecondsBreakdown' => $buildsMbSecondsBreakdown,
|
||||
|
||||
+102
-104
@@ -50,107 +50,6 @@ use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
// for returning dsn of multitype dbs with type optionally based on input dsn
|
||||
function getDatabaseDSN(string $databasetype, $region, ?string $dsn = null): string
|
||||
{
|
||||
$isSharedTablesV1 = false;
|
||||
$isSharedTablesV2 = false;
|
||||
if (!empty($dsn)) {
|
||||
try {
|
||||
$parsedDsn = new DSN($dsn);
|
||||
$dsnHost = $parsedDsn->getHost();
|
||||
} catch (\InvalidArgumentException) {
|
||||
$dsnHost = $dsn;
|
||||
}
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', ''));
|
||||
$sharedTablesV2 = \array_diff($sharedTables, $sharedTablesV1);
|
||||
$isSharedTablesV1 = \in_array($dsnHost, $sharedTablesV1);
|
||||
$isSharedTablesV2 = \in_array($dsnHost, $sharedTablesV2);
|
||||
}
|
||||
|
||||
$databases = [];
|
||||
$databaseKeys = [];
|
||||
/**
|
||||
* @var string|null $databaseOverride
|
||||
*/
|
||||
$databaseOverride = '';
|
||||
$dbScheme = '';
|
||||
$sharedTables = [];
|
||||
$sharedTablesV1 = [];
|
||||
$sharedTablesV2 = [];
|
||||
|
||||
switch ($databasetype) {
|
||||
case 'documentsDatabase':
|
||||
$databases = Config::getParam('pools-documentsdb', []);
|
||||
$databaseKeys = System::getEnv('_APP_DATABASE_DOCUMENTSDB_KEYS', '');
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_DOCUMENTSDB_OVERRIDE');
|
||||
$dbScheme = System::getEnv('_APP_DB_HOST_DOCUMENTSDB', 'mongodb');
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1', ''));
|
||||
break;
|
||||
case 'vectorDatabase':
|
||||
$databases = Config::getParam('pools-vectordb', []);
|
||||
$databaseKeys = System::getEnv('_APP_DATABASE_VECTORDB_KEYS', '');
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_VECTORDB_OVERRIDE');
|
||||
$dbScheme = System::getEnv('_APP_DB_HOST_VECTORDB', 'postgresql');
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES_V1', ''));
|
||||
break;
|
||||
default:
|
||||
// legacy/tablesdb
|
||||
$databases = Config::getParam('pools-database', []);
|
||||
$databaseKeys = System::getEnv('_APP_DATABASE_KEYS', '');
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE');
|
||||
$dbScheme = System::getEnv('_APP_DB_HOST', 'mysql');
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', ''));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($region !== 'default') {
|
||||
$keys = explode(',', $databaseKeys);
|
||||
$databases = array_filter($keys, function ($value) use ($region) {
|
||||
return str_contains($value, $region);
|
||||
});
|
||||
}
|
||||
$sharedTablesV2 = \array_diff($sharedTables, $sharedTablesV1);
|
||||
|
||||
$index = \array_search($databaseOverride, $databases);
|
||||
if ($index !== false) {
|
||||
$selectedDsn = $databases[$index];
|
||||
} else {
|
||||
if (!empty($dsn)) {
|
||||
if ($isSharedTablesV1) {
|
||||
$databases = array_filter($databases, fn ($value) => \in_array($value, $sharedTablesV1));
|
||||
} elseif ($isSharedTablesV2) {
|
||||
$databases = array_filter($databases, fn ($value) => \in_array($value, $sharedTablesV2));
|
||||
} else {
|
||||
$databases = array_filter($databases, fn ($value) => !\in_array($value, $sharedTables));
|
||||
}
|
||||
}
|
||||
$selectedDsn = !empty($databases) ? $databases[array_rand($databases)] : '';
|
||||
}
|
||||
|
||||
if (\in_array($selectedDsn, $sharedTables)) {
|
||||
$schema = 'appwrite';
|
||||
$database = 'appwrite';
|
||||
$namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', '');
|
||||
$selectedDsn = $schema . '://' . $selectedDsn . '?database=' . $database;
|
||||
|
||||
if (!empty($namespace)) {
|
||||
$selectedDsn .= '&namespace=' . $namespace;
|
||||
}
|
||||
}
|
||||
try {
|
||||
new DSN($selectedDsn);
|
||||
} catch (\InvalidArgumentException) {
|
||||
$selectedDsn = $dbScheme.'://' . $selectedDsn;
|
||||
}
|
||||
return $selectedDsn;
|
||||
}
|
||||
|
||||
App::init()
|
||||
->groups(['projects'])
|
||||
->inject('project')
|
||||
@@ -200,6 +99,105 @@ App::post('/v1/projects')
|
||||
->inject('hooks')
|
||||
->action(function (string $projectId, string $name, string $teamId, string $region, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Request $request, Response $response, Database $dbForPlatform, Cache $cache, Group $pools, Hooks $hooks) {
|
||||
|
||||
// for returning dsn of multitype dbs with type optionally based on input dsn
|
||||
$getDatabaseDSN = function (string $databasetype, $region, ?string $dsn = null): string {
|
||||
$isSharedTablesV1 = false;
|
||||
$isSharedTablesV2 = false;
|
||||
if (!empty($dsn)) {
|
||||
try {
|
||||
$parsedDsn = new DSN($dsn);
|
||||
$dsnHost = $parsedDsn->getHost();
|
||||
} catch (\InvalidArgumentException) {
|
||||
$dsnHost = $dsn;
|
||||
}
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', ''));
|
||||
$sharedTablesV2 = \array_diff($sharedTables, $sharedTablesV1);
|
||||
$isSharedTablesV1 = \in_array($dsnHost, $sharedTablesV1);
|
||||
$isSharedTablesV2 = \in_array($dsnHost, $sharedTablesV2);
|
||||
}
|
||||
|
||||
$databases = [];
|
||||
$databaseKeys = [];
|
||||
/**
|
||||
* @var string|null $databaseOverride
|
||||
*/
|
||||
$databaseOverride = '';
|
||||
$dbScheme = '';
|
||||
$sharedTables = [];
|
||||
$sharedTablesV1 = [];
|
||||
$sharedTablesV2 = [];
|
||||
|
||||
switch ($databasetype) {
|
||||
case 'documentsDatabase':
|
||||
$databases = Config::getParam('pools-documentsdb', []);
|
||||
$databaseKeys = System::getEnv('_APP_DATABASE_DOCUMENTSDB_KEYS', '');
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_DOCUMENTSDB_OVERRIDE');
|
||||
$dbScheme = System::getEnv('_APP_DB_HOST_DOCUMENTSDB', 'mongodb');
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1', ''));
|
||||
break;
|
||||
case 'vectorDatabase':
|
||||
$databases = Config::getParam('pools-vectordb', []);
|
||||
$databaseKeys = System::getEnv('_APP_DATABASE_VECTORDB_KEYS', '');
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_VECTORDB_OVERRIDE');
|
||||
$dbScheme = System::getEnv('_APP_DB_HOST_VECTORDB', 'postgresql');
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORDB_SHARED_TABLES_V1', ''));
|
||||
break;
|
||||
default:
|
||||
// legacy/tablesdb
|
||||
$databases = Config::getParam('pools-database', []);
|
||||
$databaseKeys = System::getEnv('_APP_DATABASE_KEYS', '');
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE');
|
||||
$dbScheme = System::getEnv('_APP_DB_HOST', 'mysql');
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', ''));
|
||||
break;
|
||||
}
|
||||
|
||||
if ($region !== 'default') {
|
||||
$keys = explode(',', $databaseKeys);
|
||||
$databases = array_filter($keys, function ($value) use ($region) {
|
||||
return str_contains($value, $region);
|
||||
});
|
||||
}
|
||||
$sharedTablesV2 = \array_diff($sharedTables, $sharedTablesV1);
|
||||
|
||||
$index = \array_search($databaseOverride, $databases);
|
||||
if ($index !== false) {
|
||||
$selectedDsn = $databases[$index];
|
||||
} else {
|
||||
if (!empty($dsn)) {
|
||||
if ($isSharedTablesV1) {
|
||||
$databases = array_filter($databases, fn ($value) => \in_array($value, $sharedTablesV1));
|
||||
} elseif ($isSharedTablesV2) {
|
||||
$databases = array_filter($databases, fn ($value) => \in_array($value, $sharedTablesV2));
|
||||
} else {
|
||||
$databases = array_filter($databases, fn ($value) => !\in_array($value, $sharedTables));
|
||||
}
|
||||
}
|
||||
$selectedDsn = !empty($databases) ? $databases[array_rand($databases)] : '';
|
||||
}
|
||||
|
||||
if (\in_array($selectedDsn, $sharedTables)) {
|
||||
$schema = 'appwrite';
|
||||
$database = 'appwrite';
|
||||
$namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', '');
|
||||
$selectedDsn = $schema . '://' . $selectedDsn . '?database=' . $database;
|
||||
|
||||
if (!empty($namespace)) {
|
||||
$selectedDsn .= '&namespace=' . $namespace;
|
||||
}
|
||||
}
|
||||
try {
|
||||
new DSN($selectedDsn);
|
||||
} catch (\InvalidArgumentException) {
|
||||
$selectedDsn = $dbScheme.'://' . $selectedDsn;
|
||||
}
|
||||
return $selectedDsn;
|
||||
};
|
||||
$team = $dbForPlatform->getDocument('teams', $teamId);
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
@@ -238,7 +236,7 @@ App::post('/v1/projects')
|
||||
throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project.");
|
||||
}
|
||||
|
||||
$dsn = getDatabaseDSN('databases', $region);
|
||||
$dsn = $getDatabaseDSN('databases', $region);
|
||||
|
||||
try {
|
||||
$project = $dbForPlatform->createDocument('projects', new Document([
|
||||
@@ -273,8 +271,8 @@ App::post('/v1/projects')
|
||||
'accessedAt' => DateTime::now(),
|
||||
'search' => implode(' ', [$projectId, $name]),
|
||||
'database' => $dsn,
|
||||
'documentsDatabase' => getDatabaseDSN('documentsDatabase', $region, $dsn),
|
||||
'vectorDatabase' => getDatabaseDSN('vectorDatabase', $region, $dsn)
|
||||
'documentsDatabase' => $getDatabaseDSN('documentsDatabase', $region, $dsn),
|
||||
'vectorDatabase' => $getDatabaseDSN('vectorDatabase', $region, $dsn)
|
||||
]));
|
||||
} catch (Duplicate) {
|
||||
throw new Exception(Exception::PROJECT_ALREADY_EXISTS);
|
||||
|
||||
@@ -681,7 +681,13 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
'metadata' => $metadata,
|
||||
]);
|
||||
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
try {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::STORAGE_FILE_ALREADY_EXISTS);
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
} else {
|
||||
$file = $file
|
||||
->setAttribute('$permissions', $permissions)
|
||||
@@ -731,6 +737,8 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
|
||||
try {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::STORAGE_FILE_ALREADY_EXISTS);
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -72,6 +72,18 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
|
||||
return $label;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get database type prefixed metric
|
||||
* Prefixes the metric with database type if it's not legacy or tablesdb
|
||||
*
|
||||
* @param string $databaseType Database type (e.g., 'documentsdb', 'tablesdb', 'legacy', '')
|
||||
* @param string $metric Base metric constant (e.g., METRIC_DATABASES, METRIC_COLLECTIONS)
|
||||
* @return string Prefixed metric or original metric if no prefix needed
|
||||
*/
|
||||
$getDatabaseTypePrefixedMetric = function (string $databaseType, string $metric): string {
|
||||
return implode('.', array_filter([$databaseType, $metric]));
|
||||
};
|
||||
|
||||
/**
|
||||
* This isolated event handling for `users.*.create` which is based on a `Database::EVENT_DOCUMENT_CREATE` listener may look odd, but it is **intentional**.
|
||||
*
|
||||
@@ -110,7 +122,7 @@ $eventDatabaseListener = function (Document $project, Document $document, Respon
|
||||
}
|
||||
};
|
||||
|
||||
$usageDatabaseListener = function (string $event, Document $document, StatsUsage $queueForStatsUsage) {
|
||||
$usageDatabaseListener = function (string $event, Document $document, StatsUsage $queueForStatsUsage, string $databaseType) use ($getDatabaseTypePrefixedMetric) {
|
||||
$value = 1;
|
||||
|
||||
switch ($event) {
|
||||
@@ -142,7 +154,8 @@ $usageDatabaseListener = function (string $event, Document $document, StatsUsage
|
||||
$queueForStatsUsage->addMetric(METRIC_SESSIONS, $value); //per project
|
||||
break;
|
||||
case $document->getCollection() === 'databases': // databases
|
||||
$queueForStatsUsage->addMetric(METRIC_DATABASES, $value); // per project
|
||||
$metric = $getDatabaseTypePrefixedMetric($databaseType, METRIC_DATABASES);
|
||||
$queueForStatsUsage->addMetric($metric, $value); // per project
|
||||
|
||||
if ($event === Database::EVENT_DOCUMENT_DELETE) {
|
||||
$queueForStatsUsage->addReduce($document);
|
||||
@@ -151,22 +164,29 @@ $usageDatabaseListener = function (string $event, Document $document, StatsUsage
|
||||
case str_starts_with($document->getCollection(), 'database_') && !str_contains($document->getCollection(), 'collection'): //collections
|
||||
$parts = explode('_', $document->getCollection());
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionMetric = $getDatabaseTypePrefixedMetric($databaseType, METRIC_COLLECTIONS);
|
||||
$databaseIdCollectionMetric = $getDatabaseTypePrefixedMetric($databaseType, METRIC_DATABASE_ID_COLLECTIONS);
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_COLLECTIONS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_COLLECTIONS), $value);
|
||||
->addMetric($collectionMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdCollectionMetric), $value);
|
||||
|
||||
if ($event === Database::EVENT_DOCUMENT_DELETE) {
|
||||
$queueForStatsUsage->addReduce($document);
|
||||
}
|
||||
break;
|
||||
// for databases route documents are getting created via getDatabasesDB and stats are maintained in the resources
|
||||
// but keeping it since other routes might created documents still directly via dbForProject
|
||||
case str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_'): //documents
|
||||
$parts = explode('_', $document->getCollection());
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionInternalId = $parts[3] ?? 0;
|
||||
$documentsMetric = $getDatabaseTypePrefixedMetric($databaseType, METRIC_DOCUMENTS);
|
||||
$databaseIdDocumentsMetric = $getDatabaseTypePrefixedMetric($databaseType, METRIC_DATABASE_ID_DOCUMENTS);
|
||||
$databaseIdCollectionIdDocumentsMetric = $getDatabaseTypePrefixedMetric($databaseType, METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS);
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DOCUMENTS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection
|
||||
->addMetric($documentsMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], $databaseIdCollectionIdDocumentsMetric), $value); // per collection
|
||||
break;
|
||||
case $document->getCollection() === 'buckets': //buckets
|
||||
$queueForStatsUsage
|
||||
@@ -506,6 +526,11 @@ App::init()
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Publisher $publisherFunctions, Publisher $publisherWebhooks, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry) use ($usageDatabaseListener, $eventDatabaseListener) {
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
$path = $route->getMatchedPath();
|
||||
$databaseType = match (true) {
|
||||
str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB,
|
||||
default => '',
|
||||
};
|
||||
|
||||
if (
|
||||
array_key_exists('rest', $project->getAttribute('apis', []))
|
||||
@@ -621,12 +646,14 @@ App::init()
|
||||
$queueForWebhooks = new Webhook($publisherWebhooks);
|
||||
$queueForRealtime = new Realtime();
|
||||
|
||||
// to get consumed in the stats worker without calling to database
|
||||
$queueForStatsUsage->setContext('database', new Document(['type' => $databaseType]));
|
||||
$dbForProject
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage))
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage))
|
||||
->on(Database::EVENT_DOCUMENTS_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage))
|
||||
->on(Database::EVENT_DOCUMENTS_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage))
|
||||
->on(Database::EVENT_DOCUMENTS_UPSERT, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage))
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage, $databaseType))
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage, $databaseType))
|
||||
->on(Database::EVENT_DOCUMENTS_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage, $databaseType))
|
||||
->on(Database::EVENT_DOCUMENTS_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage, $databaseType))
|
||||
->on(Database::EVENT_DOCUMENTS_UPSERT, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForStatsUsage, $databaseType))
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'create-trigger-events', fn ($event, $document) => $eventDatabaseListener(
|
||||
$project,
|
||||
$document,
|
||||
|
||||
@@ -7,6 +7,8 @@ require_once __DIR__ . '/../config/storage/resource_limits.php';
|
||||
|
||||
$configAdapter = new PHP();
|
||||
|
||||
Config::load('runtimes', __DIR__ . '/../config/runtimes.php', $configAdapter);
|
||||
Config::load('runtimes-v2', __DIR__ . '/../config/runtimes-v2.php', $configAdapter);
|
||||
Config::load('template-runtimes', __DIR__ . '/../config/template-runtimes.php', $configAdapter);
|
||||
Config::load('events', __DIR__ . '/../config/events.php', $configAdapter);
|
||||
Config::load('auth', __DIR__ . '/../config/auth.php', $configAdapter);
|
||||
@@ -17,8 +19,6 @@ Config::load('platforms', __DIR__ . '/../config/platforms.php', $configAdapter);
|
||||
Config::load('console', __DIR__ . '/../config/console.php', $configAdapter);
|
||||
Config::load('collections', __DIR__ . '/../config/collections.php', $configAdapter);
|
||||
Config::load('frameworks', __DIR__ . '/../config/frameworks.php', $configAdapter);
|
||||
Config::load('runtimes', __DIR__ . '/../config/runtimes.php', $configAdapter);
|
||||
Config::load('runtimes-v2', __DIR__ . '/../config/runtimes-v2.php', $configAdapter);
|
||||
Config::load('usage', __DIR__ . '/../config/usage.php', $configAdapter);
|
||||
Config::load('roles', __DIR__ . '/../config/roles.php', $configAdapter); // User roles and scopes
|
||||
Config::load('scopes', __DIR__ . '/../config/scopes.php', $configAdapter); // User roles and scopes
|
||||
|
||||
+21
-5
@@ -264,6 +264,22 @@ const METRIC_DATABASES_OPERATIONS_READS = 'databases.operations.reads';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_READS = '{databaseInternalId}.databases.operations.reads';
|
||||
const METRIC_DATABASES_OPERATIONS_WRITES = 'databases.operations.writes';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_WRITES = '{databaseInternalId}.databases.operations.writes';
|
||||
|
||||
// documentsdb
|
||||
const METRIC_DATABASES_DOCUMENTSDB = 'documentsdb.databases';
|
||||
const METRIC_COLLECTIONS_DOCUMENTSDB = 'documentsdb.collections';
|
||||
const METRIC_DATABASES_STORAGE_DOCUMENTSDB = 'documentsdb.databases.storage';
|
||||
const METRIC_DATABASE_ID_COLLECTIONS_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.collections';
|
||||
const METRIC_DATABASE_ID_STORAGE_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.databases.storage';
|
||||
const METRIC_DOCUMENTS_DOCUMENTSDB = 'documentsdb.documents';
|
||||
const METRIC_DATABASE_ID_DOCUMENTS_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.documents';
|
||||
const METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.{collectionInternalId}.documents';
|
||||
const METRIC_DATABASE_ID_COLLECTION_ID_STORAGE_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.{collectionInternalId}.databases.storage';
|
||||
const METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB = 'documentsdb.databases.operations.reads';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_READS_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.databases.operations.reads';
|
||||
const METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB = 'documentsdb.databases.operations.writes';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_WRITES_DOCUMENTSDB = 'documentsdb.{databaseInternalId}.databases.operations.writes';
|
||||
|
||||
const METRIC_BUCKETS = 'buckets';
|
||||
const METRIC_FILES = 'files';
|
||||
const METRIC_FILES_STORAGE = 'files.storage';
|
||||
@@ -370,10 +386,10 @@ const SCHEDULE_RESOURCE_TYPE_MESSAGE = 'message';
|
||||
const COOKIE_NAME_PREVIEW = 'a_jwt_console';
|
||||
|
||||
// Database types
|
||||
const DATABASE_LEGACY_TYPE = 'legacy';
|
||||
const DATABASE_TABLESDB_TYPE = 'tablesdb';
|
||||
const DATABASE_DOCUMENTSDB_TYPE = 'documentsdb';
|
||||
const DATABASE_VECTORDB_TYPE = 'vectordb';
|
||||
const DATABASE_TYPE_LEGACY = 'legacy';
|
||||
const DATABASE_TYPE_TABLESDB = 'tablesdb';
|
||||
const DATABASE_TYPE_DOCUMENTSDB = 'documentsdb';
|
||||
const DATABASE_TYPE_VECTORDB = 'vectordb';
|
||||
|
||||
// CSV import/export allowed database types
|
||||
const CSV_ALLOWED_DATABASE_TYPES = [DATABASE_LEGACY_TYPE, DATABASE_LEGACY_TYPE, DATABASE_VECTORDB_TYPE];
|
||||
const CSV_ALLOWED_DATABASE_TYPES = [DATABASE_TYPE_LEGACY, DATABASE_TYPE_LEGACY, DATABASE_TYPE_VECTORDB];
|
||||
|
||||
+33
-24
@@ -485,13 +485,14 @@ App::setResource('dbForPlatform', function (Group $pools, Cache $cache) {
|
||||
App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Document $project, Request $request, StatsUsage $queueForStatsUsage) {
|
||||
|
||||
return function (Document $database) use ($pools, $cache, $project, $request, $queueForStatsUsage): Database {
|
||||
$databaseType = $database->getAttribute('database', '');
|
||||
$databaseDSN = $database->getAttribute('database', '');
|
||||
$databaseType = $database->getAttribute('type', '');
|
||||
try {
|
||||
$databaseDSN = new DSN($databaseType);
|
||||
$databaseDSN = new DSN($databaseDSN);
|
||||
} catch (\InvalidArgumentException) {
|
||||
// for old databases migrated through patch script
|
||||
// databaseType determines the adapter
|
||||
$databaseDSN = new DSN('mysql://'.$databaseType);
|
||||
// databaseDSN determines the adapter
|
||||
$databaseDSN = new DSN('mysql://'.$databaseDSN);
|
||||
}
|
||||
try {
|
||||
$dsn = new DSN($project->getAttribute('database'));
|
||||
@@ -529,8 +530,16 @@ App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Documen
|
||||
}
|
||||
|
||||
// Register database event listeners for usage stats collection
|
||||
$documentsMetric = METRIC_DOCUMENTS;
|
||||
$databaseIdDocumentsMetric = METRIC_DATABASE_ID_DOCUMENTS;
|
||||
$databaseIdCollectionIdDocumentsMetric = METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS;
|
||||
if ($databaseType !== DATABASE_TYPE_LEGACY && $databaseType !== DATABASE_TYPE_TABLESDB) {
|
||||
$documentsMetric = $databaseType. '.' .$documentsMetric;
|
||||
$databaseIdDocumentsMetric = $databaseType. '.' .$databaseIdDocumentsMetric;
|
||||
$databaseIdCollectionIdDocumentsMetric = $databaseType . '.' .$databaseIdCollectionIdDocumentsMetric;
|
||||
}
|
||||
$database
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) {
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage, $documentsMetric, $databaseIdDocumentsMetric, $databaseIdCollectionIdDocumentsMetric) {
|
||||
$value = 1;
|
||||
|
||||
if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) {
|
||||
@@ -538,12 +547,12 @@ App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Documen
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionInternalId = $parts[3] ?? 0;
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DOCUMENTS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection
|
||||
->addMetric($documentsMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], $databaseIdCollectionIdDocumentsMetric), $value); // per collection
|
||||
}
|
||||
})
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) {
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage, $documentsMetric, $databaseIdDocumentsMetric, $databaseIdCollectionIdDocumentsMetric) {
|
||||
$value = -1;
|
||||
|
||||
if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) {
|
||||
@@ -551,12 +560,12 @@ App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Documen
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionInternalId = $parts[3] ?? 0;
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DOCUMENTS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection
|
||||
->addMetric($documentsMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], $databaseIdCollectionIdDocumentsMetric), $value); // per collection
|
||||
}
|
||||
})
|
||||
->on(Database::EVENT_DOCUMENTS_CREATE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) {
|
||||
->on(Database::EVENT_DOCUMENTS_CREATE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage, $documentsMetric, $databaseIdDocumentsMetric, $databaseIdCollectionIdDocumentsMetric) {
|
||||
$value = $document->getAttribute('modified', 0);
|
||||
|
||||
if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) {
|
||||
@@ -564,12 +573,12 @@ App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Documen
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionInternalId = $parts[3] ?? 0;
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DOCUMENTS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection
|
||||
->addMetric($documentsMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], $databaseIdCollectionIdDocumentsMetric), $value); // per collection
|
||||
}
|
||||
})
|
||||
->on(Database::EVENT_DOCUMENTS_DELETE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) {
|
||||
->on(Database::EVENT_DOCUMENTS_DELETE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage, $documentsMetric, $databaseIdDocumentsMetric, $databaseIdCollectionIdDocumentsMetric) {
|
||||
$value = -1 * $document->getAttribute('modified', 0);
|
||||
|
||||
if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) {
|
||||
@@ -577,12 +586,12 @@ App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Documen
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionInternalId = $parts[3] ?? 0;
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DOCUMENTS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection
|
||||
->addMetric($documentsMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], $databaseIdCollectionIdDocumentsMetric), $value); // per collection
|
||||
}
|
||||
})
|
||||
->on(Database::EVENT_DOCUMENTS_UPSERT, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) {
|
||||
->on(Database::EVENT_DOCUMENTS_UPSERT, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage, $documentsMetric, $databaseIdDocumentsMetric, $databaseIdCollectionIdDocumentsMetric) {
|
||||
$value = $document->getAttribute('created', 0);
|
||||
|
||||
if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) {
|
||||
@@ -590,9 +599,9 @@ App::setResource('getDatabasesDB', function (Group $pools, Cache $cache, Documen
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$collectionInternalId = $parts[3] ?? 0;
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DOCUMENTS, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection
|
||||
->addMetric($documentsMetric, $value) // per project
|
||||
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric), $value) // per database
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], $databaseIdCollectionIdDocumentsMetric), $value); // per collection
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+40
-37
@@ -8,6 +8,7 @@ use Appwrite\PubSub\Adapter\Pool as PubSubPool;
|
||||
use Appwrite\Utopia\Database\Documents\User;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Swoole\Coroutine;
|
||||
use Swoole\Http\Request as SwooleRequest;
|
||||
use Swoole\Http\Response as SwooleResponse;
|
||||
use Swoole\Runtime;
|
||||
@@ -52,14 +53,14 @@ Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
if (!function_exists('getConsoleDB')) {
|
||||
function getConsoleDB(): Database
|
||||
{
|
||||
global $register;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
static $database = null;
|
||||
|
||||
if ($database !== null) {
|
||||
return $database;
|
||||
if (isset($ctx['dbForPlatform'])) {
|
||||
return $ctx['dbForPlatform'];
|
||||
}
|
||||
|
||||
global $register;
|
||||
|
||||
/** @var Group $pools */
|
||||
$pools = $register->get('pools');
|
||||
|
||||
@@ -69,10 +70,8 @@ if (!function_exists('getConsoleDB')) {
|
||||
->setNamespace('_console')
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', '_console');
|
||||
|
||||
$database->setDocumentType('users', User::class);
|
||||
|
||||
return $database;
|
||||
return $ctx['dbForPlatform'] = $database;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,14 +79,18 @@ if (!function_exists('getConsoleDB')) {
|
||||
if (!function_exists('getProjectDB')) {
|
||||
function getProjectDB(Document $project): Database
|
||||
{
|
||||
global $register;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
static $databases = [];
|
||||
|
||||
if (isset($databases[$project->getSequence()])) {
|
||||
return $databases[$project->getSequence()];
|
||||
if (!isset($ctx['dbForProject'])) {
|
||||
$ctx['dbForProject'] = [];
|
||||
}
|
||||
|
||||
if (isset($ctx['dbForProject'][$project->getSequence()])) {
|
||||
return $ctx['dbForProject'][$project->getSequence()];
|
||||
}
|
||||
|
||||
global $register;
|
||||
|
||||
/** @var Group $pools */
|
||||
$pools = $register->get('pools');
|
||||
|
||||
@@ -125,7 +128,7 @@ if (!function_exists('getProjectDB')) {
|
||||
|
||||
$database->setDocumentType('users', User::class);
|
||||
|
||||
return $databases[$project->getSequence()] = $database;
|
||||
return $ctx['dbForProject'][$project->getSequence()] = $database;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,14 +136,14 @@ if (!function_exists('getProjectDB')) {
|
||||
if (!function_exists('getCache')) {
|
||||
function getCache(): Cache
|
||||
{
|
||||
global $register;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
static $cache = null;
|
||||
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
if (isset($ctx['cache'])) {
|
||||
return $ctx['cache'];
|
||||
}
|
||||
|
||||
global $register;
|
||||
|
||||
$pools = $register->get('pools'); /** @var Group $pools */
|
||||
|
||||
$list = Config::getParam('pools-cache', []);
|
||||
@@ -150,7 +153,7 @@ if (!function_exists('getCache')) {
|
||||
$adapters[] = new CachePool($pools->get($value));
|
||||
}
|
||||
|
||||
return $cache = new Cache(new Sharding($adapters));
|
||||
return $ctx['cache'] = new Cache(new Sharding($adapters));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,10 +161,10 @@ if (!function_exists('getCache')) {
|
||||
if (!function_exists('getRedis')) {
|
||||
function getRedis(): \Redis
|
||||
{
|
||||
static $redis = null;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
if ($redis !== null) {
|
||||
return $redis;
|
||||
if (isset($ctx['redis'])) {
|
||||
return $ctx['redis'];
|
||||
}
|
||||
|
||||
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
|
||||
@@ -175,46 +178,46 @@ if (!function_exists('getRedis')) {
|
||||
}
|
||||
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
return $redis;
|
||||
return $ctx['redis'] = $redis;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getTimelimit')) {
|
||||
function getTimelimit(): TimeLimitRedis
|
||||
function getTimelimit(string $key = "", int $limit = 0, int $seconds = 1): TimeLimitRedis
|
||||
{
|
||||
static $timelimit = null;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
if ($timelimit !== null) {
|
||||
return $timelimit;
|
||||
if (isset($ctx['timelimit'])) {
|
||||
return $ctx['timelimit'];
|
||||
}
|
||||
|
||||
return $timelimit = new TimeLimitRedis("", 0, 1, getRedis());
|
||||
return $ctx['timelimit'] = new TimeLimitRedis($key, $limit, $seconds, getRedis());
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getRealtime')) {
|
||||
function getRealtime(): Realtime
|
||||
{
|
||||
static $realtime = null;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
if ($realtime !== null) {
|
||||
return $realtime;
|
||||
if (isset($ctx['realtime'])) {
|
||||
return $ctx['realtime'];
|
||||
}
|
||||
|
||||
return $realtime = new Realtime();
|
||||
return $ctx['realtime'] = new Realtime();
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getTelemetry')) {
|
||||
function getTelemetry(int $workerId): Utopia\Telemetry\Adapter
|
||||
{
|
||||
static $telemetry = null;
|
||||
$ctx = Coroutine::getContext();
|
||||
|
||||
if ($telemetry !== null) {
|
||||
return $telemetry;
|
||||
if (isset($ctx['telemetry'])) {
|
||||
return $ctx['telemetry'];
|
||||
}
|
||||
|
||||
return $telemetry = new NoTelemetry();
|
||||
return $ctx['telemetry'] = new NoTelemetry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@
|
||||
"utopia-php/detector": "0.2.*",
|
||||
"utopia-php/domains": "0.9.*",
|
||||
"utopia-php/emails": "0.6.*",
|
||||
"utopia-php/dns": "1.1.*",
|
||||
"utopia-php/dns": "1.4.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/fetch": "0.4.*",
|
||||
|
||||
Generated
+72
-71
@@ -754,16 +754,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v4.33.1",
|
||||
"version": "v4.33.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "0cd73ccf0cd26c3e72299cce1ea6144091a57e12"
|
||||
"reference": "fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/0cd73ccf0cd26c3e72299cce1ea6144091a57e12",
|
||||
"reference": "0cd73ccf0cd26c3e72299cce1ea6144091a57e12",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318",
|
||||
"reference": "fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -792,9 +792,9 @@
|
||||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.1"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.2"
|
||||
},
|
||||
"time": "2025-11-12T21:58:05+00:00"
|
||||
"time": "2025-12-05T22:12:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
@@ -2668,16 +2668,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client",
|
||||
"version": "v7.4.0",
|
||||
"version": "v7.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client.git",
|
||||
"reference": "ee5e0e0139ab506f6063a230e631bed677c650a4"
|
||||
"reference": "26cc224ea7103dda90e9694d9e139a389092d007"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/ee5e0e0139ab506f6063a230e631bed677c650a4",
|
||||
"reference": "ee5e0e0139ab506f6063a230e631bed677c650a4",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/26cc224ea7103dda90e9694d9e139a389092d007",
|
||||
"reference": "26cc224ea7103dda90e9694d9e139a389092d007",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2745,7 +2745,7 @@
|
||||
"http"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.4.0"
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.4.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2765,7 +2765,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-20T12:32:50+00:00"
|
||||
"time": "2025-12-04T21:12:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client-contracts",
|
||||
@@ -4048,16 +4048,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/dns",
|
||||
"version": "1.1.4",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/dns.git",
|
||||
"reference": "eea6b9299a1420ae6c574f16eb1e9da8689ac56b"
|
||||
"reference": "dce3453364a4524b7250db8d8eb74820b814409e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/eea6b9299a1420ae6c574f16eb1e9da8689ac56b",
|
||||
"reference": "eea6b9299a1420ae6c574f16eb1e9da8689ac56b",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/dce3453364a4524b7250db8d8eb74820b814409e",
|
||||
"reference": "dce3453364a4524b7250db8d8eb74820b814409e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4099,9 +4099,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/dns/issues",
|
||||
"source": "https://github.com/utopia-php/dns/tree/1.1.4"
|
||||
"source": "https://github.com/utopia-php/dns/tree/1.4.0"
|
||||
},
|
||||
"time": "2025-11-26T13:38:10+00:00"
|
||||
"time": "2025-12-05T10:09:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
@@ -4313,29 +4313,29 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.33",
|
||||
"version": "0.33.34",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "838e3a28276e73187bc34a314f014096dc92191b"
|
||||
"reference": "76def92594c32504ec80eaacdb60ff8fad73c856"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/838e3a28276e73187bc34a314f014096dc92191b",
|
||||
"reference": "838e3a28276e73187bc34a314f014096dc92191b",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/76def92594c32504ec80eaacdb60ff8fad73c856",
|
||||
"reference": "76def92594c32504ec80eaacdb60ff8fad73c856",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"php": ">=8.3",
|
||||
"utopia-php/compression": "0.1.*",
|
||||
"utopia-php/telemetry": "0.1.*",
|
||||
"utopia-php/validators": "0.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.2",
|
||||
"phpbench/phpbench": "^1.2",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.5.25"
|
||||
"laravel/pint": "1.*",
|
||||
"phpbench/phpbench": "1.*",
|
||||
"phpstan/phpstan": "1.*",
|
||||
"phpunit/phpunit": "9.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -4355,9 +4355,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.33"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.34"
|
||||
},
|
||||
"time": "2025-11-25T10:21:13+00:00"
|
||||
"time": "2025-12-08T07:55:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
@@ -4728,16 +4728,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/platform",
|
||||
"version": "0.7.12",
|
||||
"version": "0.7.13",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/platform.git",
|
||||
"reference": "04255de21db75e90b170040f4d1b457ba721e7a5"
|
||||
"reference": "77a863a920122e2c6a6bc6ee5548d366a3f4c6c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/04255de21db75e90b170040f4d1b457ba721e7a5",
|
||||
"reference": "04255de21db75e90b170040f4d1b457ba721e7a5",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/77a863a920122e2c6a6bc6ee5548d366a3f4c6c7",
|
||||
"reference": "77a863a920122e2c6a6bc6ee5548d366a3f4c6c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4750,6 +4750,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
"phpstan/phpstan": "2.*",
|
||||
"phpunit/phpunit": "9.*"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -4772,9 +4773,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/platform/issues",
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.12"
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.13"
|
||||
},
|
||||
"time": "2025-09-05T15:53:12+00:00"
|
||||
"time": "2025-12-08T10:02:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
@@ -5001,16 +5002,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.18.14",
|
||||
"version": "0.18.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "4f14ec952c6f4006dd0613e55bbf7631814fbc00"
|
||||
"reference": "0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/4f14ec952c6f4006dd0613e55bbf7631814fbc00",
|
||||
"reference": "4f14ec952c6f4006dd0613e55bbf7631814fbc00",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f",
|
||||
"reference": "0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5053,9 +5054,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.18.14"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.18.16"
|
||||
},
|
||||
"time": "2025-10-07T10:21:47+00:00"
|
||||
"time": "2025-12-03T02:15:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
@@ -6009,16 +6010,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v5.6.2",
|
||||
"version": "v5.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "3a454ca033b9e06b63282ce19562e892747449bb"
|
||||
"reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb",
|
||||
"reference": "3a454ca033b9e06b63282ce19562e892747449bb",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
|
||||
"reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6061,9 +6062,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0"
|
||||
},
|
||||
"time": "2025-10-21T19:32:17+00:00"
|
||||
"time": "2025-12-06T11:56:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@@ -6712,16 +6713,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.6.30",
|
||||
"version": "9.6.31",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "b69489b312503bf8fa6d75a76916919d7d2fa6d4"
|
||||
"reference": "945d0b7f346a084ce5549e95289962972c4272e5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b69489b312503bf8fa6d75a76916919d7d2fa6d4",
|
||||
"reference": "b69489b312503bf8fa6d75a76916919d7d2fa6d4",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/945d0b7f346a084ce5549e95289962972c4272e5",
|
||||
"reference": "945d0b7f346a084ce5549e95289962972c4272e5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -6795,7 +6796,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.30"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.31"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -6819,7 +6820,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-01T07:35:08+00:00"
|
||||
"time": "2025-12-06T07:45:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/cache",
|
||||
@@ -7979,16 +7980,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "307d3cf852f5ead3618ac60ecbedbdd512c348b1"
|
||||
"reference": "fcb73f69d655b48fcb894a262f074218df08bd58"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/307d3cf852f5ead3618ac60ecbedbdd512c348b1",
|
||||
"reference": "307d3cf852f5ead3618ac60ecbedbdd512c348b1",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fcb73f69d655b48fcb894a262f074218df08bd58",
|
||||
"reference": "fcb73f69d655b48fcb894a262f074218df08bd58",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8045,7 +8046,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8065,20 +8066,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-21T13:19:49+00:00"
|
||||
"time": "2025-12-05T15:25:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "7fc96ae83372620eaba3826874f46e26295768ca"
|
||||
"reference": "d937d400b980523dc9ee946bb69972b5e619058d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/7fc96ae83372620eaba3826874f46e26295768ca",
|
||||
"reference": "7fc96ae83372620eaba3826874f46e26295768ca",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/d937d400b980523dc9ee946bb69972b5e619058d",
|
||||
"reference": "d937d400b980523dc9ee946bb69972b5e619058d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8115,7 +8116,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v8.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8135,7 +8136,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-05T14:36:47+00:00"
|
||||
"time": "2025-12-01T09:13:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
@@ -8673,16 +8674,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f929eccf09531078c243df72398560e32fa4cf4f"
|
||||
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f929eccf09531078c243df72398560e32fa4cf4f",
|
||||
"reference": "f929eccf09531078c243df72398560e32fa4cf4f",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc",
|
||||
"reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -8739,7 +8740,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/string/tree/v8.0.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -8759,7 +8760,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-09-11T14:37:55+00:00"
|
||||
"time": "2025-12-01T09:13:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
|
||||
@@ -13,24 +13,27 @@ Avatars avatars = new Avatars(client);
|
||||
|
||||
avatars.getScreenshot(
|
||||
"https://example.com", // url
|
||||
Map.of("a", "b"), // headers (optional)
|
||||
1, // viewportWidth (optional)
|
||||
1, // viewportHeight (optional)
|
||||
0.1, // scale (optional)
|
||||
Map.of(
|
||||
"Authorization", "Bearer token123",
|
||||
"X-Custom-Header", "value"
|
||||
), // headers (optional)
|
||||
1920, // viewportWidth (optional)
|
||||
1080, // viewportHeight (optional)
|
||||
2, // scale (optional)
|
||||
Theme.LIGHT, // theme (optional)
|
||||
"<USER_AGENT>", // userAgent (optional)
|
||||
false, // fullpage (optional)
|
||||
"<LOCALE>", // locale (optional)
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // userAgent (optional)
|
||||
true, // fullpage (optional)
|
||||
"en-US", // locale (optional)
|
||||
Timezone.AFRICA_ABIDJAN, // timezone (optional)
|
||||
-90, // latitude (optional)
|
||||
-180, // longitude (optional)
|
||||
0, // accuracy (optional)
|
||||
false, // touch (optional)
|
||||
List.of(), // permissions (optional)
|
||||
0, // sleep (optional)
|
||||
0, // width (optional)
|
||||
0, // height (optional)
|
||||
-1, // quality (optional)
|
||||
37.7749, // latitude (optional)
|
||||
-122.4194, // longitude (optional)
|
||||
100, // accuracy (optional)
|
||||
true, // touch (optional)
|
||||
List.of("geolocation", "notifications"), // permissions (optional)
|
||||
3, // sleep (optional)
|
||||
800, // width (optional)
|
||||
600, // height (optional)
|
||||
85, // quality (optional)
|
||||
Output.JPG, // output (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -13,23 +13,26 @@ val avatars = Avatars(client)
|
||||
|
||||
val result = avatars.getScreenshot(
|
||||
url = "https://example.com",
|
||||
headers = mapOf( "a" to "b" ), // (optional)
|
||||
viewportWidth = 1, // (optional)
|
||||
viewportHeight = 1, // (optional)
|
||||
scale = 0.1, // (optional)
|
||||
headers = mapOf(
|
||||
"Authorization" to "Bearer token123",
|
||||
"X-Custom-Header" to "value"
|
||||
), // (optional)
|
||||
viewportWidth = 1920, // (optional)
|
||||
viewportHeight = 1080, // (optional)
|
||||
scale = 2, // (optional)
|
||||
theme = theme.LIGHT, // (optional)
|
||||
userAgent = "<USER_AGENT>", // (optional)
|
||||
fullpage = false, // (optional)
|
||||
locale = "<LOCALE>", // (optional)
|
||||
userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // (optional)
|
||||
fullpage = true, // (optional)
|
||||
locale = "en-US", // (optional)
|
||||
timezone = timezone.AFRICA_ABIDJAN, // (optional)
|
||||
latitude = -90, // (optional)
|
||||
longitude = -180, // (optional)
|
||||
accuracy = 0, // (optional)
|
||||
touch = false, // (optional)
|
||||
permissions = listOf(), // (optional)
|
||||
sleep = 0, // (optional)
|
||||
width = 0, // (optional)
|
||||
height = 0, // (optional)
|
||||
quality = -1, // (optional)
|
||||
latitude = 37.7749, // (optional)
|
||||
longitude = -122.4194, // (optional)
|
||||
accuracy = 100, // (optional)
|
||||
touch = true, // (optional)
|
||||
permissions = listOf("geolocation", "notifications"), // (optional)
|
||||
sleep = 3, // (optional)
|
||||
width = 800, // (optional)
|
||||
height = 600, // (optional)
|
||||
quality = 85, // (optional)
|
||||
output = output.JPG, // (optional)
|
||||
)
|
||||
@@ -9,24 +9,27 @@ let avatars = Avatars(client)
|
||||
|
||||
let bytes = try await avatars.getScreenshot(
|
||||
url: "https://example.com",
|
||||
headers: [:], // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: [
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
], // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: .light, // optional
|
||||
userAgent: "<USER_AGENT>", // optional
|
||||
fullpage: false, // optional
|
||||
locale: "<LOCALE>", // optional
|
||||
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // optional
|
||||
fullpage: true, // optional
|
||||
locale: "en-US", // optional
|
||||
timezone: .africaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: .jpg // optional
|
||||
)
|
||||
|
||||
|
||||
@@ -9,24 +9,27 @@ Avatars avatars = Avatars(client);
|
||||
// Downloading file
|
||||
Uint8List bytes = await avatars.getScreenshot(
|
||||
url: 'https://example.com',
|
||||
headers: {}, // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: Theme.light, // optional
|
||||
userAgent: '<USER_AGENT>', // optional
|
||||
fullpage: false, // optional
|
||||
locale: '<LOCALE>', // optional
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // optional
|
||||
fullpage: true, // optional
|
||||
locale: 'en-US', // optional
|
||||
timezone: Timezone.africaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: Output.jpg, // optional
|
||||
)
|
||||
|
||||
@@ -37,24 +40,27 @@ file.writeAsBytesSync(bytes);
|
||||
FutureBuilder(
|
||||
future: avatars.getScreenshot(
|
||||
url:'https://example.com' ,
|
||||
headers:{} , // optional
|
||||
viewportWidth:1 , // optional
|
||||
viewportHeight:1 , // optional
|
||||
scale:0.1 , // optional
|
||||
headers:{
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
} , // optional
|
||||
viewportWidth:1920 , // optional
|
||||
viewportHeight:1080 , // optional
|
||||
scale:2 , // optional
|
||||
theme: Theme.light, // optional
|
||||
userAgent:'<USER_AGENT>' , // optional
|
||||
fullpage:false , // optional
|
||||
locale:'<LOCALE>' , // optional
|
||||
userAgent:'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15' , // optional
|
||||
fullpage:true , // optional
|
||||
locale:'en-US' , // optional
|
||||
timezone: Timezone.africaAbidjan, // optional
|
||||
latitude:-90 , // optional
|
||||
longitude:-180 , // optional
|
||||
accuracy:0 , // optional
|
||||
touch:false , // optional
|
||||
permissions:[] , // optional
|
||||
sleep:0 , // optional
|
||||
width:0 , // optional
|
||||
height:0 , // optional
|
||||
quality:-1 , // optional
|
||||
latitude:37.7749 , // optional
|
||||
longitude:-122.4194 , // optional
|
||||
accuracy:100 , // optional
|
||||
touch:true , // optional
|
||||
permissions:["geolocation","notifications"] , // optional
|
||||
sleep:3 , // optional
|
||||
width:800 , // optional
|
||||
height:600 , // optional
|
||||
quality:85 , // optional
|
||||
output: Output.jpg, // optional
|
||||
), // Works for both public file and private file, for private files you need to be logged in
|
||||
builder: (context, snapshot) {
|
||||
|
||||
@@ -8,24 +8,27 @@ const avatars = new Avatars(client);
|
||||
|
||||
const result = avatars.getScreenshot({
|
||||
url: 'https://example.com',
|
||||
headers: {}, // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: Theme.Light, // optional
|
||||
userAgent: '<USER_AGENT>', // optional
|
||||
fullpage: false, // optional
|
||||
locale: '<LOCALE>', // optional
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // optional
|
||||
fullpage: true, // optional
|
||||
locale: 'en-US', // optional
|
||||
timezone: Timezone.AfricaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: Output.Jpg // optional
|
||||
});
|
||||
|
||||
|
||||
@@ -8,24 +8,27 @@ const avatars = new Avatars(client);
|
||||
|
||||
const result = avatars.getScreenshot({
|
||||
url: 'https://example.com',
|
||||
headers: {}, // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: Theme.Light, // optional
|
||||
userAgent: '<USER_AGENT>', // optional
|
||||
fullpage: false, // optional
|
||||
locale: '<LOCALE>', // optional
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // optional
|
||||
fullpage: true, // optional
|
||||
locale: 'en-US', // optional
|
||||
timezone: Timezone.AfricaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: Output.Jpg // optional
|
||||
});
|
||||
|
||||
|
||||
@@ -8,24 +8,27 @@ const avatars = new Avatars(client);
|
||||
|
||||
const result = avatars.getScreenshot({
|
||||
url: 'https://example.com',
|
||||
headers: {}, // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: Theme.Light, // optional
|
||||
userAgent: '<USER_AGENT>', // optional
|
||||
fullpage: false, // optional
|
||||
locale: '<LOCALE>', // optional
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // optional
|
||||
fullpage: true, // optional
|
||||
locale: 'en-US', // optional
|
||||
timezone: Timezone.AfricaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: Output.Jpg // optional
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ const vcs = new Vcs(client);
|
||||
const result = await vcs.listRepositories({
|
||||
installationId: '<INSTALLATION_ID>',
|
||||
type: VCSDetectionType.Runtime,
|
||||
search: '<SEARCH>' // optional
|
||||
search: '<SEARCH>', // optional
|
||||
queries: [] // optional
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -9,23 +9,26 @@ Avatars avatars = Avatars(client);
|
||||
|
||||
Uint8List result = await avatars.getScreenshot(
|
||||
url: 'https://example.com',
|
||||
headers: {}, // (optional)
|
||||
viewportWidth: 1, // (optional)
|
||||
viewportHeight: 1, // (optional)
|
||||
scale: 0.1, // (optional)
|
||||
headers: {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, // (optional)
|
||||
viewportWidth: 1920, // (optional)
|
||||
viewportHeight: 1080, // (optional)
|
||||
scale: 2, // (optional)
|
||||
theme: Theme.light, // (optional)
|
||||
userAgent: '<USER_AGENT>', // (optional)
|
||||
fullpage: false, // (optional)
|
||||
locale: '<LOCALE>', // (optional)
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // (optional)
|
||||
fullpage: true, // (optional)
|
||||
locale: 'en-US', // (optional)
|
||||
timezone: Timezone.africaAbidjan, // (optional)
|
||||
latitude: -90, // (optional)
|
||||
longitude: -180, // (optional)
|
||||
accuracy: 0, // (optional)
|
||||
touch: false, // (optional)
|
||||
permissions: [], // (optional)
|
||||
sleep: 0, // (optional)
|
||||
width: 0, // (optional)
|
||||
height: 0, // (optional)
|
||||
quality: -1, // (optional)
|
||||
latitude: 37.7749, // (optional)
|
||||
longitude: -122.4194, // (optional)
|
||||
accuracy: 100, // (optional)
|
||||
touch: true, // (optional)
|
||||
permissions: ["geolocation","notifications"], // (optional)
|
||||
sleep: 3, // (optional)
|
||||
width: 800, // (optional)
|
||||
height: 600, // (optional)
|
||||
quality: 85, // (optional)
|
||||
output: Output.jpg, // (optional)
|
||||
);
|
||||
|
||||
@@ -12,23 +12,26 @@ Avatars avatars = new Avatars(client);
|
||||
|
||||
byte[] result = await avatars.GetScreenshot(
|
||||
url: "https://example.com",
|
||||
headers: [object], // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: new {
|
||||
Authorization = "Bearer token123",
|
||||
X-Custom-Header = "value"
|
||||
}, // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: Theme.Light, // optional
|
||||
userAgent: "<USER_AGENT>", // optional
|
||||
fullpage: false, // optional
|
||||
locale: "<LOCALE>", // optional
|
||||
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // optional
|
||||
fullpage: true, // optional
|
||||
locale: "en-US", // optional
|
||||
timezone: Timezone.AfricaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: new List<string>(), // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: Output.Jpg // optional
|
||||
);
|
||||
@@ -16,23 +16,26 @@ service := avatars.New(client)
|
||||
|
||||
response, error := service.GetScreenshot(
|
||||
"https://example.com",
|
||||
avatars.WithGetScreenshotHeaders(map[string]interface{}{}),
|
||||
avatars.WithGetScreenshotViewportWidth(1),
|
||||
avatars.WithGetScreenshotViewportHeight(1),
|
||||
avatars.WithGetScreenshotScale(0.1),
|
||||
avatars.WithGetScreenshotTheme("light"),
|
||||
avatars.WithGetScreenshotUserAgent("<USER_AGENT>"),
|
||||
avatars.WithGetScreenshotFullpage(false),
|
||||
avatars.WithGetScreenshotLocale("<LOCALE>"),
|
||||
avatars.WithGetScreenshotTimezone("africa/abidjan"),
|
||||
avatars.WithGetScreenshotLatitude(-90),
|
||||
avatars.WithGetScreenshotLongitude(-180),
|
||||
avatars.WithGetScreenshotAccuracy(0),
|
||||
avatars.WithGetScreenshotTouch(false),
|
||||
avatars.WithGetScreenshotPermissions([]interface{}{}),
|
||||
avatars.WithGetScreenshotSleep(0),
|
||||
avatars.WithGetScreenshotWidth(0),
|
||||
avatars.WithGetScreenshotHeight(0),
|
||||
avatars.WithGetScreenshotQuality(-1),
|
||||
avatars.WithGetScreenshotOutput("jpg"),
|
||||
avatars.WithGetScreenshotHeaders(map[string]interface{}{
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}),
|
||||
avatars.WithGetScreenshotViewportWidth(1920),
|
||||
avatars.WithGetScreenshotViewportHeight(1080),
|
||||
avatars.WithGetScreenshotScale(2),
|
||||
avatars.WithGetScreenshotTheme("dark"),
|
||||
avatars.WithGetScreenshotUserAgent("Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15"),
|
||||
avatars.WithGetScreenshotFullpage(true),
|
||||
avatars.WithGetScreenshotLocale("en-US"),
|
||||
avatars.WithGetScreenshotTimezone("America/New_York"),
|
||||
avatars.WithGetScreenshotLatitude(37.7749),
|
||||
avatars.WithGetScreenshotLongitude(-122.4194),
|
||||
avatars.WithGetScreenshotAccuracy(100),
|
||||
avatars.WithGetScreenshotTouch(true),
|
||||
avatars.WithGetScreenshotPermissions(interface{}{"geolocation","notifications"}),
|
||||
avatars.WithGetScreenshotSleep(3),
|
||||
avatars.WithGetScreenshotWidth(800),
|
||||
avatars.WithGetScreenshotHeight(600),
|
||||
avatars.WithGetScreenshotQuality(85),
|
||||
avatars.WithGetScreenshotOutput("jpeg"),
|
||||
)
|
||||
|
||||
@@ -14,24 +14,27 @@ Avatars avatars = new Avatars(client);
|
||||
|
||||
avatars.getScreenshot(
|
||||
"https://example.com", // url
|
||||
Map.of("a", "b"), // headers (optional)
|
||||
1, // viewportWidth (optional)
|
||||
1, // viewportHeight (optional)
|
||||
0.1, // scale (optional)
|
||||
Map.of(
|
||||
"Authorization", "Bearer token123",
|
||||
"X-Custom-Header", "value"
|
||||
), // headers (optional)
|
||||
1920, // viewportWidth (optional)
|
||||
1080, // viewportHeight (optional)
|
||||
2, // scale (optional)
|
||||
Theme.LIGHT, // theme (optional)
|
||||
"<USER_AGENT>", // userAgent (optional)
|
||||
false, // fullpage (optional)
|
||||
"<LOCALE>", // locale (optional)
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // userAgent (optional)
|
||||
true, // fullpage (optional)
|
||||
"en-US", // locale (optional)
|
||||
Timezone.AFRICA_ABIDJAN, // timezone (optional)
|
||||
-90, // latitude (optional)
|
||||
-180, // longitude (optional)
|
||||
0, // accuracy (optional)
|
||||
false, // touch (optional)
|
||||
List.of(), // permissions (optional)
|
||||
0, // sleep (optional)
|
||||
0, // width (optional)
|
||||
0, // height (optional)
|
||||
-1, // quality (optional)
|
||||
37.7749, // latitude (optional)
|
||||
-122.4194, // longitude (optional)
|
||||
100, // accuracy (optional)
|
||||
true, // touch (optional)
|
||||
List.of("geolocation", "notifications"), // permissions (optional)
|
||||
3, // sleep (optional)
|
||||
800, // width (optional)
|
||||
600, // height (optional)
|
||||
85, // quality (optional)
|
||||
Output.JPG, // output (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -14,23 +14,26 @@ val avatars = Avatars(client)
|
||||
|
||||
val result = avatars.getScreenshot(
|
||||
url = "https://example.com",
|
||||
headers = mapOf( "a" to "b" ), // optional
|
||||
viewportWidth = 1, // optional
|
||||
viewportHeight = 1, // optional
|
||||
scale = 0.1, // optional
|
||||
theme = "light", // optional
|
||||
userAgent = "<USER_AGENT>", // optional
|
||||
fullpage = false, // optional
|
||||
locale = "<LOCALE>", // optional
|
||||
timezone = "africa/abidjan", // optional
|
||||
latitude = -90, // optional
|
||||
longitude = -180, // optional
|
||||
accuracy = 0, // optional
|
||||
touch = false, // optional
|
||||
permissions = listOf(), // optional
|
||||
sleep = 0, // optional
|
||||
width = 0, // optional
|
||||
height = 0, // optional
|
||||
quality = -1, // optional
|
||||
output = "jpg" // optional
|
||||
headers = mapOf(
|
||||
"Authorization" to "Bearer token123",
|
||||
"X-Custom-Header" to "value"
|
||||
), // optional
|
||||
viewportWidth = 1920, // optional
|
||||
viewportHeight = 1080, // optional
|
||||
scale = 2, // optional
|
||||
theme = "dark", // optional
|
||||
userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // optional
|
||||
fullpage = true, // optional
|
||||
locale = "en-US", // optional
|
||||
timezone = "America/New_York", // optional
|
||||
latitude = 37.7749, // optional
|
||||
longitude = -122.4194, // optional
|
||||
accuracy = 100, // optional
|
||||
touch = true, // optional
|
||||
permissions = listOf("geolocation", "notifications"), // optional
|
||||
sleep = 3, // optional
|
||||
width = 800, // optional
|
||||
height = 600, // optional
|
||||
quality = 85, // optional
|
||||
output = "jpeg" // optional
|
||||
)
|
||||
|
||||
@@ -9,23 +9,26 @@ const avatars = new sdk.Avatars(client);
|
||||
|
||||
const result = await avatars.getScreenshot({
|
||||
url: 'https://example.com',
|
||||
headers: {}, // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: sdk.Theme.Light, // optional
|
||||
userAgent: '<USER_AGENT>', // optional
|
||||
fullpage: false, // optional
|
||||
locale: '<LOCALE>', // optional
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // optional
|
||||
fullpage: true, // optional
|
||||
locale: 'en-US', // optional
|
||||
timezone: sdk.Timezone.AfricaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: sdk.Output.Jpg // optional
|
||||
});
|
||||
|
||||
@@ -15,23 +15,26 @@ $avatars = new Avatars($client);
|
||||
|
||||
$result = $avatars->getScreenshot(
|
||||
url: 'https://example.com',
|
||||
headers: [], // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: [
|
||||
'Authorization' => 'Bearer token123',
|
||||
'X-Custom-Header' => 'value'
|
||||
], // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: Theme::LIGHT(), // optional
|
||||
userAgent: '<USER_AGENT>', // optional
|
||||
fullpage: false, // optional
|
||||
locale: '<LOCALE>', // optional
|
||||
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', // optional
|
||||
fullpage: true, // optional
|
||||
locale: 'en-US', // optional
|
||||
timezone: Timezone::AFRICAABIDJAN(), // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: Output::JPG() // optional
|
||||
);
|
||||
@@ -13,23 +13,26 @@ avatars = Avatars(client)
|
||||
|
||||
result = avatars.get_screenshot(
|
||||
url = 'https://example.com',
|
||||
headers = {}, # optional
|
||||
viewport_width = 1, # optional
|
||||
viewport_height = 1, # optional
|
||||
scale = 0.1, # optional
|
||||
headers = {
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
}, # optional
|
||||
viewport_width = 1920, # optional
|
||||
viewport_height = 1080, # optional
|
||||
scale = 2, # optional
|
||||
theme = Theme.LIGHT, # optional
|
||||
user_agent = '<USER_AGENT>', # optional
|
||||
fullpage = False, # optional
|
||||
locale = '<LOCALE>', # optional
|
||||
user_agent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', # optional
|
||||
fullpage = True, # optional
|
||||
locale = 'en-US', # optional
|
||||
timezone = Timezone.AFRICA_ABIDJAN, # optional
|
||||
latitude = -90, # optional
|
||||
longitude = -180, # optional
|
||||
accuracy = 0, # optional
|
||||
touch = False, # optional
|
||||
permissions = [], # optional
|
||||
sleep = 0, # optional
|
||||
width = 0, # optional
|
||||
height = 0, # optional
|
||||
quality = -1, # optional
|
||||
latitude = 37.7749, # optional
|
||||
longitude = -122.4194, # optional
|
||||
accuracy = 100, # optional
|
||||
touch = True, # optional
|
||||
permissions = ["geolocation","notifications"], # optional
|
||||
sleep = 3, # optional
|
||||
width = 800, # optional
|
||||
height = 600, # optional
|
||||
quality = 85, # optional
|
||||
output = Output.JPG # optional
|
||||
)
|
||||
|
||||
@@ -12,23 +12,26 @@ avatars = Avatars.new(client)
|
||||
|
||||
result = avatars.get_screenshot(
|
||||
url: 'https://example.com',
|
||||
headers: {}, # optional
|
||||
viewport_width: 1, # optional
|
||||
viewport_height: 1, # optional
|
||||
scale: 0.1, # optional
|
||||
headers: {
|
||||
"Authorization" => "Bearer token123",
|
||||
"X-Custom-Header" => "value"
|
||||
}, # optional
|
||||
viewport_width: 1920, # optional
|
||||
viewport_height: 1080, # optional
|
||||
scale: 2, # optional
|
||||
theme: Theme::LIGHT, # optional
|
||||
user_agent: '<USER_AGENT>', # optional
|
||||
fullpage: false, # optional
|
||||
locale: '<LOCALE>', # optional
|
||||
user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15', # optional
|
||||
fullpage: true, # optional
|
||||
locale: 'en-US', # optional
|
||||
timezone: Timezone::AFRICA_ABIDJAN, # optional
|
||||
latitude: -90, # optional
|
||||
longitude: -180, # optional
|
||||
accuracy: 0, # optional
|
||||
touch: false, # optional
|
||||
permissions: [], # optional
|
||||
sleep: 0, # optional
|
||||
width: 0, # optional
|
||||
height: 0, # optional
|
||||
quality: -1, # optional
|
||||
latitude: 37.7749, # optional
|
||||
longitude: -122.4194, # optional
|
||||
accuracy: 100, # optional
|
||||
touch: true, # optional
|
||||
permissions: ["geolocation","notifications"], # optional
|
||||
sleep: 3, # optional
|
||||
width: 800, # optional
|
||||
height: 600, # optional
|
||||
quality: 85, # optional
|
||||
output: Output::JPG # optional
|
||||
)
|
||||
|
||||
@@ -10,24 +10,27 @@ let avatars = Avatars(client)
|
||||
|
||||
let bytes = try await avatars.getScreenshot(
|
||||
url: "https://example.com",
|
||||
headers: [:], // optional
|
||||
viewportWidth: 1, // optional
|
||||
viewportHeight: 1, // optional
|
||||
scale: 0.1, // optional
|
||||
headers: [
|
||||
"Authorization": "Bearer token123",
|
||||
"X-Custom-Header": "value"
|
||||
], // optional
|
||||
viewportWidth: 1920, // optional
|
||||
viewportHeight: 1080, // optional
|
||||
scale: 2, // optional
|
||||
theme: .light, // optional
|
||||
userAgent: "<USER_AGENT>", // optional
|
||||
fullpage: false, // optional
|
||||
locale: "<LOCALE>", // optional
|
||||
userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15", // optional
|
||||
fullpage: true, // optional
|
||||
locale: "en-US", // optional
|
||||
timezone: .africaAbidjan, // optional
|
||||
latitude: -90, // optional
|
||||
longitude: -180, // optional
|
||||
accuracy: 0, // optional
|
||||
touch: false, // optional
|
||||
permissions: [], // optional
|
||||
sleep: 0, // optional
|
||||
width: 0, // optional
|
||||
height: 0, // optional
|
||||
quality: -1, // optional
|
||||
latitude: 37.7749, // optional
|
||||
longitude: -122.4194, // optional
|
||||
accuracy: 100, // optional
|
||||
touch: true, // optional
|
||||
permissions: ["geolocation","notifications"], // optional
|
||||
sleep: 3, // optional
|
||||
width: 800, // optional
|
||||
height: 600, // optional
|
||||
quality: 85, // optional
|
||||
output: .jpg // optional
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Change Log
|
||||
|
||||
## 11.4.0
|
||||
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 11.3.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Change Log
|
||||
|
||||
## 13.5.0
|
||||
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 13.4.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Change Log
|
||||
|
||||
## 12.0.1
|
||||
|
||||
Fix type generation for `point`, `lineString` and `polygon` columns
|
||||
|
||||
## 12.0.0
|
||||
|
||||
* Change `create-deployment-template`'s `version` parameter to `type` and `reference`. eg. usage - `create-deployment-template --type tag --reference 1.0.0`
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Change Log
|
||||
|
||||
## 20.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `createTemplateDeployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 19.4.0
|
||||
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## 0.23.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `CreateTemplateDeployment` method signature: replace `Version` parameter with `Type` (TemplateReferenceType) and `Reference` parameters
|
||||
* Add `GetScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 0.22.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
## 20.3.1
|
||||
|
||||
* Fix passing of `null` values and stripping only non-nullable optional parameters from the request body
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 20.3.0
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## v0.15.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `CreateTemplateDeployment` method signature: replace `Version` parameter with `Type` (TemplateReferenceType) and `Reference` parameters
|
||||
* Add `GetScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## v0.14.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## 13.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `createTemplateDeployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 12.3.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## 21.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `createTemplateDeployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 20.3.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Change Log
|
||||
|
||||
## 19.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `createTemplateDeployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 18.0.1
|
||||
|
||||
* Fix `TablesDB` service to use correct file name
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Change Log
|
||||
|
||||
## 14.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `create_template_deployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `get_screenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
* Add support for dart39 and flutter335 runtimes
|
||||
|
||||
## 13.6.1
|
||||
|
||||
* Fix passing of `None` to nullable parameters
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Change log
|
||||
|
||||
## 0.19.0
|
||||
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 0.18.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## 20.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `create_template_deployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `get_screenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 19.3.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Change Log
|
||||
|
||||
## 14.0.0
|
||||
|
||||
* Rename `VCSDeploymentType` enum to `VCSReferenceType`
|
||||
* Change `createTemplateDeployment` method signature: replace `version` parameter with `type` (TemplateReferenceType) and `reference` parameters
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 13.3.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
# Change Log
|
||||
|
||||
## 21.5.0
|
||||
|
||||
* Add `getScreenshot` method to `Avatars` service
|
||||
* Add `Theme`, `Timezone` and `Output` enums
|
||||
|
||||
## 21.4.0
|
||||
|
||||
* Add `total` parameter to list queries allowing skipping counting rows in a table for improved performance
|
||||
|
||||
@@ -52,9 +52,9 @@ class TransactionState
|
||||
?string $transactionId = null,
|
||||
array $queries = []
|
||||
): Document {
|
||||
$databasesDB = ($this->getDatabasesDB)($database);
|
||||
$dbForDatabases = ($this->getDatabasesDB)($database);
|
||||
if ($transactionId === null) {
|
||||
return $databasesDB->getDocument($collectionId, $documentId, $queries);
|
||||
return $dbForDatabases->getDocument($collectionId, $documentId, $queries);
|
||||
}
|
||||
|
||||
$state = $this->getTransactionState($transactionId);
|
||||
@@ -72,7 +72,7 @@ class TransactionState
|
||||
|
||||
if ($docState['action'] === 'update' || $docState['action'] === 'upsert') {
|
||||
// Merge with committed version
|
||||
$committedDoc = $databasesDB->getDocument($collectionId, $documentId, $queries);
|
||||
$committedDoc = $dbForDatabases->getDocument($collectionId, $documentId, $queries);
|
||||
if (!$committedDoc->isEmpty()) {
|
||||
foreach ($docState['document']->getAttributes() as $key => $value) {
|
||||
if ($key !== '$id') {
|
||||
@@ -86,7 +86,7 @@ class TransactionState
|
||||
}
|
||||
}
|
||||
}
|
||||
return $databasesDB->getDocument($collectionId, $documentId, $queries);
|
||||
return $dbForDatabases->getDocument($collectionId, $documentId, $queries);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,14 +107,14 @@ class TransactionState
|
||||
?string $transactionId = null,
|
||||
array $queries = []
|
||||
): array {
|
||||
$databasesDB = ($this->getDatabasesDB)($database);
|
||||
$dbForDatabases = ($this->getDatabasesDB)($database);
|
||||
// If no transaction, use normal database retrieval
|
||||
if ($transactionId === null) {
|
||||
return $databasesDB->find($collectionId, $queries);
|
||||
return $dbForDatabases->find($collectionId, $queries);
|
||||
}
|
||||
|
||||
$state = $this->getTransactionState($transactionId);
|
||||
$committedDocs = $databasesDB->find($collectionId, $queries);
|
||||
$committedDocs = $dbForDatabases->find($collectionId, $queries);
|
||||
$documentMap = [];
|
||||
|
||||
// Build map of committed documents
|
||||
@@ -170,18 +170,18 @@ class TransactionState
|
||||
?string $transactionId = null,
|
||||
array $queries = []
|
||||
): int {
|
||||
$databasesDB = ($this->getDatabasesDB)($database);
|
||||
$dbForDatabases = ($this->getDatabasesDB)($database);
|
||||
if ($transactionId === null) {
|
||||
return $databasesDB->count($collectionId, $queries, APP_LIMIT_COUNT);
|
||||
return $dbForDatabases->count($collectionId, $queries, APP_LIMIT_COUNT);
|
||||
}
|
||||
|
||||
$state = $this->getTransactionState($transactionId);
|
||||
$baseCount = $databasesDB->count($collectionId, $queries, APP_LIMIT_COUNT);
|
||||
$baseCount = $dbForDatabases->count($collectionId, $queries, APP_LIMIT_COUNT);
|
||||
|
||||
if (!isset($state[$collectionId])) {
|
||||
return $baseCount;
|
||||
}
|
||||
$committedDocs = $databasesDB->find($collectionId, $queries);
|
||||
$committedDocs = $dbForDatabases->find($collectionId, $queries);
|
||||
$committedDocIds = [];
|
||||
foreach ($committedDocs as $doc) {
|
||||
$committedDocIds[$doc->getId()] = true;
|
||||
|
||||
@@ -475,6 +475,9 @@ class Event
|
||||
$patterns = [];
|
||||
|
||||
$parsed = self::parseEventPattern($pattern);
|
||||
// to switch the resource types from databases to the required prefix
|
||||
// eg; all databases events get fired with databases. prefix which mainly depicts legacy type
|
||||
// so a projection from databases to the actual prefix(documentsdb, vectordb,etc)
|
||||
if ((str_contains($pattern, 'databases.') && $database && $database->getAttribute('type') !== 'legacy')) {
|
||||
$parsed = self::getDatabaseTypeEvents($database, $parsed);
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ class StatsUsage extends Event
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
'context' => $this->context,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use Utopia\Database\Operator;
|
||||
|
||||
class Action extends AppwriteAction
|
||||
{
|
||||
private string $context = 'legacy';
|
||||
private string $context = DATABASE_TYPE_LEGACY;
|
||||
|
||||
public function getDatabaseType(): string
|
||||
{
|
||||
@@ -20,10 +20,10 @@ class Action extends AppwriteAction
|
||||
public function setHttpPath(string $path): AppwriteAction
|
||||
{
|
||||
if (\str_contains($path, '/tablesdb')) {
|
||||
$this->context = 'tablesdb';
|
||||
$this->context = DATABASE_TYPE_TABLESDB;
|
||||
}
|
||||
if (\str_contains($path, '/documentsdb')) {
|
||||
$this->context = 'documentsdb';
|
||||
$this->context = DATABASE_TYPE_DOCUMENTSDB;
|
||||
}
|
||||
if (\str_contains($path, '/vectordb')) {
|
||||
$this->context = 'vectordb';
|
||||
|
||||
@@ -118,4 +118,64 @@ abstract class Action extends UtopiaAction
|
||||
? Exception::COLLECTION_LIMIT_EXCEEDED
|
||||
: Exception::TABLE_LIMIT_EXCEEDED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate format unsupported exception.
|
||||
*/
|
||||
protected function getFormatUnsupportedException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI()
|
||||
? Exception::ATTRIBUTE_FORMAT_UNSUPPORTED
|
||||
: Exception::COLUMN_FORMAT_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct default unsupported message.
|
||||
*/
|
||||
protected function getDefaultUnsupportedException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI()
|
||||
? Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED
|
||||
: Exception::COLUMN_DEFAULT_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate parent level not found exception.
|
||||
*/
|
||||
protected function getParentNotFoundException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI()
|
||||
? Exception::COLLECTION_NOT_FOUND
|
||||
: Exception::TABLE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct invalid structure message.
|
||||
*/
|
||||
protected function getStructureException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI()
|
||||
? Exception::DOCUMENT_INVALID_STRUCTURE
|
||||
: Exception::ROW_INVALID_STRUCTURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception for unknown attribute/column in index.
|
||||
*/
|
||||
protected function getParentUnknownException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI()
|
||||
? Exception::ATTRIBUTE_UNKNOWN
|
||||
: Exception::COLUMN_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception for invalid attribute/column type in index.
|
||||
*/
|
||||
protected function getParentInvalidTypeException(): string
|
||||
{
|
||||
return $this->isCollectionsAPI()
|
||||
? Exception::ATTRIBUTE_TYPE_INVALID
|
||||
: Exception::COLUMN_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Attributes as AttributesValidator;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Database\Validator\Indexes as IndexesValidator;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -20,10 +22,13 @@ use Utopia\Database\Exception\NotFound as NotFoundException;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Index as IndexValidator;
|
||||
use Utopia\Database\Validator\Permissions;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\JSON;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
@@ -75,6 +80,8 @@ class Create extends Action
|
||||
->param('permissions', null, new Nullable(new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE)), 'An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('documentSecurity', false, new Boolean(true), 'Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('enabled', true, new Boolean(), 'Is collection enabled? When set to \'disabled\', users cannot access the collection but Server SDKs with and API key can still read and write to the collection. No data is lost when this is toggled.', true)
|
||||
->param('attributes', [], new ArrayList(new JSON(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of attribute definitions to create. Each attribute should contain: key (string), type (string: string, integer, float, boolean, datetime, relationship), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options.', true)
|
||||
->param('indexes', [], new ArrayList(new JSON(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of attribute keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional).', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('getDatabasesDB')
|
||||
@@ -82,7 +89,7 @@ class Create extends Action
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, UtopiaResponse $response, Database $dbForProject, callable $getDatabasesDB, Event $queueForEvents): void
|
||||
public function action(string $databaseId, string $collectionId, string $name, ?array $permissions, bool $documentSecurity, bool $enabled, array $attributes, array $indexes, UtopiaResponse $response, Database $dbForProject, callable $getDatabasesDB, Event $queueForEvents): void
|
||||
{
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
@@ -113,24 +120,129 @@ class Create extends Action
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Database $dbForDatabases
|
||||
*/
|
||||
$dbForDatabases = $getDatabasesDB($database);
|
||||
|
||||
$collectionKey = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence();
|
||||
$databaseKey = 'database_' . $database->getSequence();
|
||||
|
||||
$attributesValidator = new AttributesValidator(
|
||||
APP_LIMIT_ARRAY_PARAMS_SIZE,
|
||||
$dbForDatabases->getAdapter()->getSupportForSpatialAttributes(),
|
||||
$dbForDatabases->getAdapter()->getSupportForAttributes()
|
||||
);
|
||||
|
||||
if (!$attributesValidator->isValid($attributes)) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $attributesValidator->getDescription());
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if (($attribute['type'] ?? '') === Database::VAR_RELATIONSHIP) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Relationship attributes cannot be created inline. Use the create relationship endpoint instead.');
|
||||
}
|
||||
}
|
||||
|
||||
$collectionAttributes = [];
|
||||
$attributeDocuments = [];
|
||||
try {
|
||||
foreach ($attributes as $attributeDef) {
|
||||
$attrDoc = $this->buildAttributeDocument($database, $collection, $attributeDef);
|
||||
$collectionAttributes[] = $attrDoc['collection'];
|
||||
$attributeDocuments[] = $attrDoc['document'];
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Validate indexes
|
||||
$indexesValidator = new IndexesValidator($dbForDatabases->getLimitForIndexes());
|
||||
if (!$indexesValidator->isValid($indexes)) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $indexesValidator->getDescription());
|
||||
}
|
||||
|
||||
$collectionIndexes = [];
|
||||
$indexDocuments = [];
|
||||
try {
|
||||
foreach ($indexes as $indexDef) {
|
||||
$idxDoc = $this->buildIndexDocument($database, $collection, $indexDef, $collectionAttributes);
|
||||
$collectionIndexes[] = $idxDoc['collection'];
|
||||
$indexDocuments[] = $idxDoc['document'];
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Validate indexes with DB adapter capabilities
|
||||
$indexValidator = new IndexValidator(
|
||||
$collectionAttributes,
|
||||
[],
|
||||
$dbForDatabases->getAdapter()->getMaxIndexLength(),
|
||||
$dbForDatabases->getAdapter()->getInternalIndexesKeys(),
|
||||
$dbForDatabases->getAdapter()->getSupportForIndexArray(),
|
||||
$dbForDatabases->getAdapter()->getSupportForSpatialIndexNull(),
|
||||
$dbForDatabases->getAdapter()->getSupportForSpatialIndexOrder(),
|
||||
$dbForDatabases->getAdapter()->getSupportForVectors(),
|
||||
$dbForDatabases->getAdapter()->getSupportForAttributes(),
|
||||
$dbForDatabases->getAdapter()->getSupportForMultipleFulltextIndexes(),
|
||||
$dbForDatabases->getAdapter()->getSupportForIdenticalIndexes()
|
||||
);
|
||||
|
||||
foreach ($collectionIndexes as $indexDoc) {
|
||||
if (!$indexValidator->isValid($indexDoc)) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception($this->getInvalidIndexException(), $indexValidator->getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$dbForDatabases->createCollection(
|
||||
id: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(),
|
||||
id: $collectionKey,
|
||||
attributes: $collectionAttributes,
|
||||
indexes: $collectionIndexes,
|
||||
permissions: $permissions,
|
||||
documentSecurity: $documentSecurity
|
||||
);
|
||||
} catch (DuplicateException) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception($this->getDuplicateException());
|
||||
} catch (IndexException) {
|
||||
throw new Exception($this->getInvalidIndexException());
|
||||
} catch (IndexException $e) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception($this->getInvalidIndexException(), $e->getMessage());
|
||||
} catch (LimitException) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw new Exception($this->getLimitException());
|
||||
} catch (\Throwable $e) {
|
||||
$dbForProject->deleteDocument($databaseKey, $collection->getId());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
// Create documents in attributes and indexes collections
|
||||
try {
|
||||
if (!empty($attributeDocuments)) {
|
||||
$dbForProject->createDocuments('attributes', $attributeDocuments);
|
||||
}
|
||||
if (!empty($indexDocuments)) {
|
||||
$dbForProject->createDocuments('indexes', $indexDocuments);
|
||||
}
|
||||
} catch (DuplicateException) {
|
||||
$this->cleanup($dbForProject, $databaseKey, $collectionKey, $collection->getId());
|
||||
throw new Exception($this->getDuplicateException());
|
||||
} catch (\Throwable $e) {
|
||||
$this->cleanup($dbForProject, $databaseKey, $collectionKey, $collection->getId());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getSequence(), $collection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
|
||||
$queueForEvents
|
||||
->setContext('database', $database)
|
||||
->setParam('databaseId', $databaseId)
|
||||
@@ -140,4 +252,167 @@ class Create extends Action
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_CREATED)
|
||||
->dynamic($collection, $this->getResponseModel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build attribute Document objects from a definition array
|
||||
*
|
||||
* @return array{collection: Document, document: Document}
|
||||
*/
|
||||
protected function buildAttributeDocument(
|
||||
Document $database,
|
||||
Document $collection,
|
||||
array $attribute,
|
||||
): array {
|
||||
$key = $attribute['key'];
|
||||
$type = $attribute['type'];
|
||||
$size = $attribute['size'] ?? 0;
|
||||
$required = $attribute['required'] ?? false;
|
||||
$signed = $attribute['signed'] ?? true;
|
||||
$array = $attribute['array'] ?? false;
|
||||
$format = $attribute['format'] ?? '';
|
||||
$formatOptions = [];
|
||||
$filters = $attribute['filters'] ?? [];
|
||||
$default = $attribute['default'] ?? null;
|
||||
|
||||
if ($format === APP_DATABASE_ATTRIBUTE_ENUM && isset($attribute['elements'])) {
|
||||
$formatOptions = ['elements' => $attribute['elements']];
|
||||
}
|
||||
|
||||
if (isset($attribute['min']) || isset($attribute['max'])) {
|
||||
$format = $type === Database::VAR_INTEGER
|
||||
? APP_DATABASE_ATTRIBUTE_INT_RANGE
|
||||
: APP_DATABASE_ATTRIBUTE_FLOAT_RANGE;
|
||||
|
||||
$formatOptions = [
|
||||
'min' => $attribute['min'] ?? ($type === Database::VAR_INTEGER ? \PHP_INT_MIN : -\PHP_FLOAT_MAX),
|
||||
'max' => $attribute['max'] ?? ($type === Database::VAR_INTEGER ? \PHP_INT_MAX : \PHP_FLOAT_MAX),
|
||||
];
|
||||
}
|
||||
|
||||
$collectionDoc = new Document([
|
||||
'$id' => $key,
|
||||
'key' => $key,
|
||||
'type' => $type,
|
||||
'size' => $size,
|
||||
'required' => $required,
|
||||
'signed' => $signed,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => $format,
|
||||
'formatOptions' => $formatOptions,
|
||||
'filters' => $filters,
|
||||
]);
|
||||
|
||||
$document = new Document([
|
||||
'$id' => ID::custom($database->getSequence() . '_' . $collection->getSequence() . '_' . $key),
|
||||
'key' => $key,
|
||||
'databaseInternalId' => $database->getSequence(),
|
||||
'databaseId' => $database->getId(),
|
||||
'collectionInternalId' => $collection->getSequence(),
|
||||
'collectionId' => $collection->getId(),
|
||||
'type' => $type,
|
||||
'status' => 'available',
|
||||
'size' => $size,
|
||||
'required' => $required,
|
||||
'signed' => $signed,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => $format,
|
||||
'formatOptions' => $formatOptions,
|
||||
'filters' => $filters,
|
||||
]);
|
||||
|
||||
return [
|
||||
'collection' => $collectionDoc,
|
||||
'document' => $document,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build index Document objects from a definition array
|
||||
*
|
||||
* @return array{collection: Document, document: Document}
|
||||
*/
|
||||
protected function buildIndexDocument(Document $database, Document $collection, array $indexDef, array $attributeDocuments): array
|
||||
{
|
||||
$key = $indexDef['key'];
|
||||
$type = $indexDef['type'];
|
||||
$indexAttributes = $indexDef['attributes'];
|
||||
$orders = $indexDef['orders'] ?? [];
|
||||
$lengths = $indexDef['lengths'] ?? [];
|
||||
|
||||
$attrKeys = array_map(fn ($a) => $a->getAttribute('key'), $attributeDocuments);
|
||||
|
||||
// Build lengths and orders based on attribute properties
|
||||
foreach ($indexAttributes as $i => $attr) {
|
||||
$attrIndex = array_search($attr, $attrKeys);
|
||||
if ($attrIndex !== false) {
|
||||
$attrDoc = $attributeDocuments[$attrIndex];
|
||||
$attrArray = $attrDoc->getAttribute('array', false);
|
||||
|
||||
if (empty($lengths[$i])) {
|
||||
$lengths[$i] = null;
|
||||
}
|
||||
|
||||
if ($attrArray === true) {
|
||||
$lengths[$i] = Database::MAX_ARRAY_INDEX_LENGTH;
|
||||
$orders[$i] = null;
|
||||
}
|
||||
} else {
|
||||
if (empty($lengths[$i])) {
|
||||
$lengths[$i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$collectionDoc = new Document([
|
||||
'$id' => $key,
|
||||
'key' => $key,
|
||||
'type' => $type,
|
||||
'attributes' => $indexAttributes,
|
||||
'lengths' => $lengths,
|
||||
'orders' => $orders,
|
||||
]);
|
||||
|
||||
$document = new Document([
|
||||
'$id' => ID::custom($database->getSequence() . '_' . $collection->getSequence() . '_' . $key),
|
||||
'key' => $key,
|
||||
'status' => 'available',
|
||||
'databaseInternalId' => $database->getSequence(),
|
||||
'databaseId' => $database->getId(),
|
||||
'collectionInternalId' => $collection->getSequence(),
|
||||
'collectionId' => $collection->getId(),
|
||||
'type' => $type,
|
||||
'attributes' => $indexAttributes,
|
||||
'lengths' => $lengths,
|
||||
'orders' => $orders,
|
||||
]);
|
||||
|
||||
return [
|
||||
'collection' => $collectionDoc,
|
||||
'document' => $document,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup on failure: delete the collection document and the underlying DB collection
|
||||
*/
|
||||
protected function cleanup(
|
||||
Database $dbForProject,
|
||||
string $databaseId,
|
||||
string $collectionId,
|
||||
string $collectionDocumentId
|
||||
): void {
|
||||
try {
|
||||
$dbForProject->deleteCollection($collectionId);
|
||||
} catch (\Throwable) {
|
||||
// Ignore cleanup errors for collection deletion
|
||||
}
|
||||
|
||||
try {
|
||||
$dbForProject->deleteDocument($databaseId, $collectionDocumentId);
|
||||
} catch (\Throwable) {
|
||||
// Ignore cleanup errors for document deletion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+36
@@ -15,6 +15,7 @@ abstract class Action extends DatabasesAction
|
||||
* @var string|null The current context (either 'row' or 'document')
|
||||
*/
|
||||
private ?string $context = DOCUMENTS;
|
||||
private ?string $databaseType = DATABASE_TYPE_LEGACY;
|
||||
|
||||
/**
|
||||
* Get the response model used in the SDK and HTTP responses.
|
||||
@@ -25,6 +26,8 @@ abstract class Action extends DatabasesAction
|
||||
{
|
||||
if (str_contains($path, '/tablesdb/')) {
|
||||
$this->context = ROWS;
|
||||
} elseif (str_contains($path, '/documentsdb/')) {
|
||||
$this->databaseType = DATABASE_TYPE_DOCUMENTSDB;
|
||||
}
|
||||
|
||||
$contextId = '$' . $this->getCollectionsEventsContext() . 'Id';
|
||||
@@ -43,6 +46,39 @@ abstract class Action extends DatabasesAction
|
||||
return parent::setHttpPath($path);
|
||||
}
|
||||
|
||||
protected function getDatabasesOperationReadMetric(): string
|
||||
{
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === DATABASE_TYPE_TABLESDB) {
|
||||
return METRIC_DATABASES_OPERATIONS_READS;
|
||||
}
|
||||
return $this->databaseType.'.'.METRIC_DATABASES_OPERATIONS_READS;
|
||||
}
|
||||
|
||||
protected function getDatabasesIdOperationReadMetric(): string
|
||||
{
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === DATABASE_TYPE_TABLESDB) {
|
||||
return METRIC_DATABASE_ID_OPERATIONS_READS;
|
||||
}
|
||||
return $this->databaseType.'.'.METRIC_DATABASE_ID_OPERATIONS_READS;
|
||||
}
|
||||
|
||||
protected function getDatabasesOperationWriteMetric(): string
|
||||
{
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === DATABASE_TYPE_TABLESDB) {
|
||||
return METRIC_DATABASES_OPERATIONS_WRITES;
|
||||
}
|
||||
return $this->databaseType.'.'.METRIC_DATABASES_OPERATIONS_WRITES;
|
||||
|
||||
}
|
||||
|
||||
protected function getDatabasesIdOperationWriteMetric(): string
|
||||
{
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === DATABASE_TYPE_TABLESDB) {
|
||||
return METRIC_DATABASE_ID_OPERATIONS_WRITES;
|
||||
}
|
||||
return $this->databaseType.'.'.METRIC_DATABASE_ID_OPERATIONS_WRITES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plural of the given name.
|
||||
*
|
||||
|
||||
+2
-2
@@ -200,8 +200,8 @@ class Decrement extends Action
|
||||
);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, 1)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), 1);
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), 1)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), 1);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('databaseId', $databaseId)
|
||||
|
||||
+2
-2
@@ -200,8 +200,8 @@ class Increment extends Action
|
||||
);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, 1)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), 1);
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), 1)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), 1);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('databaseId', $databaseId)
|
||||
|
||||
+2
-2
@@ -189,8 +189,8 @@ class Delete extends Action
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), \max(1, $modified));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $modified,
|
||||
|
||||
+2
-2
@@ -220,8 +220,8 @@ class Update extends Action
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), \max(1, $modified));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $modified,
|
||||
|
||||
+2
-2
@@ -195,8 +195,8 @@ class Upsert extends Action
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $modified));
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), \max(1, $modified))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), \max(1, $modified));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $modified,
|
||||
|
||||
+3
-4
@@ -83,8 +83,7 @@ class Create extends Action
|
||||
new Parameter('documentId', optional: false),
|
||||
new Parameter('data', optional: false),
|
||||
new Parameter('permissions', optional: true),
|
||||
new Parameter('transactionId', optional: true),
|
||||
new Parameter('transactionId', optional: true),
|
||||
new Parameter('transactionId', optional: true)
|
||||
],
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
@@ -482,8 +481,8 @@ class Create extends Action
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations)); // per collection
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), \max(1, $operations)); // per collection
|
||||
|
||||
$response->setStatusCode(SwooleResponse::STATUS_CODE_CREATED);
|
||||
|
||||
|
||||
+2
-4
@@ -84,8 +84,6 @@ class Delete extends Action
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('transactionState')
|
||||
->inject('plan')
|
||||
->inject('transactionState')
|
||||
->inject('plan')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -213,8 +211,8 @@ class Delete extends Action
|
||||
);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, 1)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), 1); // per collection
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), 1)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), 1); // per collection
|
||||
|
||||
$response->addHeader('X-Debug-Operations', 1);
|
||||
|
||||
|
||||
+2
-3
@@ -71,7 +71,6 @@ class Get extends Action
|
||||
->inject('getDatabasesDB')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('transactionState')
|
||||
->inject('transactionState')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -133,8 +132,8 @@ class Get extends Action
|
||||
);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS), $operations);
|
||||
->addMetric($this->getDatabasesOperationReadMetric(), max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationReadMetric()), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
|
||||
|
||||
+2
-4
@@ -88,8 +88,6 @@ class Update extends Action
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('transactionState')
|
||||
->inject('plan')
|
||||
->inject('transactionState')
|
||||
->inject('plan')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -247,8 +245,8 @@ class Update extends Action
|
||||
$setCollection($collection, $newDocument);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations);
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), $operations);
|
||||
|
||||
// Handle transaction staging
|
||||
if ($transactionId !== null) {
|
||||
|
||||
+2
-4
@@ -92,8 +92,6 @@ class Upsert extends Action
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('transactionState')
|
||||
->inject('plan')
|
||||
->inject('transactionState')
|
||||
->inject('plan')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -259,8 +257,8 @@ class Upsert extends Action
|
||||
$setCollection($collection, $newDocument);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES), \max(1, $operations));
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), \max(1, $operations))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationWriteMetric()), \max(1, $operations));
|
||||
|
||||
// Handle transaction staging
|
||||
if ($transactionId !== null) {
|
||||
|
||||
+2
-3
@@ -75,7 +75,6 @@ class XList extends Action
|
||||
->inject('getDatabasesDB')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('transactionState')
|
||||
->inject('transactionState')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -168,8 +167,8 @@ class XList extends Action
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS), $operations);
|
||||
->addMetric($this->getDatabasesOperationReadMetric(), max($operations, 1))
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getSequence(), $this->getDatabasesIdOperationReadMetric()), $operations);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $total,
|
||||
|
||||
+8
-7
@@ -110,8 +110,11 @@ class Create extends Action
|
||||
if ($count >= $limit) {
|
||||
throw new Exception($this->getLimitException(), 'Index limit exceeded');
|
||||
}
|
||||
// Convert Document array to array of attribute metadata
|
||||
$oldAttributes = \array_map(fn ($a) => $a->getArrayCopy(), $collection->getAttribute('attributes'));
|
||||
|
||||
$oldAttributes = \array_map(
|
||||
fn ($a) => $a->getArrayCopy(),
|
||||
$collection->getAttribute('attributes')
|
||||
);
|
||||
|
||||
$oldAttributes[] = [
|
||||
'key' => '$id',
|
||||
@@ -122,7 +125,6 @@ class Create extends Action
|
||||
'default' => null,
|
||||
'size' => Database::LENGTH_KEY
|
||||
];
|
||||
|
||||
$oldAttributes[] = [
|
||||
'key' => '$createdAt',
|
||||
'type' => Database::VAR_DATETIME,
|
||||
@@ -133,7 +135,6 @@ class Create extends Action
|
||||
'default' => null,
|
||||
'size' => 0
|
||||
];
|
||||
|
||||
$oldAttributes[] = [
|
||||
'key' => '$updatedAt',
|
||||
'type' => Database::VAR_DATETIME,
|
||||
@@ -163,7 +164,6 @@ class Create extends Action
|
||||
throw new Exception($this->getParentInvalidTypeException(), "Cannot create an index for a relationship $contextType: " . $oldAttributes[$attributeIndex]['key']);
|
||||
}
|
||||
|
||||
// Ensure attribute is available
|
||||
if ($attributeStatus !== 'available') {
|
||||
$contextType = ucfirst($contextType);
|
||||
throw new Exception($this->getParentNotAvailableException(), "$contextType not available: " . $oldAttributes[$attributeIndex]['key']);
|
||||
@@ -174,11 +174,12 @@ class Create extends Action
|
||||
}
|
||||
|
||||
if ($attributeArray === true) {
|
||||
$lengths[$i] = Database::MAX_ARRAY_INDEX_LENGTH;
|
||||
$orders[$i] = null;
|
||||
// Because of a bug in MySQL, we cannot create indexes on array attributes for now, otherwise queries break.
|
||||
throw new Exception(Exception::INDEX_INVALID, 'Creating indexes on array attributes is not currently supported.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$index = new Document([
|
||||
'$id' => ID::custom($db->getSequence() . '_' . $collection->getSequence() . '_' . $key),
|
||||
'key' => $key,
|
||||
|
||||
@@ -31,6 +31,11 @@ class Get extends Action
|
||||
return UtopiaResponse::MODEL_USAGE_COLLECTION;
|
||||
}
|
||||
|
||||
protected function getMetric(): string
|
||||
{
|
||||
return METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -82,7 +87,7 @@ class Get extends Action
|
||||
$stats = $usage = [];
|
||||
$days = $periods[$range];
|
||||
$metrics = [
|
||||
str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collectionDocument->getSequence()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS),
|
||||
str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collectionDocument->getSequence()], $this->getMetric()),
|
||||
];
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
|
||||
@@ -17,6 +17,22 @@ abstract class Action extends DatabasesAction
|
||||
return $this->databaseType;
|
||||
}
|
||||
|
||||
protected function getDatabasesOperationWriteMetric(): string
|
||||
{
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === TABLESDB) {
|
||||
return METRIC_DATABASES_OPERATIONS_WRITES;
|
||||
}
|
||||
return $this->databaseType.'.'.METRIC_DATABASES_OPERATIONS_WRITES;
|
||||
|
||||
}
|
||||
protected function getDatabasesIdOperationWriteMetric(): string
|
||||
{
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === TABLESDB) {
|
||||
return METRIC_DATABASE_ID_OPERATIONS_WRITES;
|
||||
}
|
||||
return $this->databaseType.'.'.METRIC_DATABASE_ID_OPERATIONS_WRITES;
|
||||
}
|
||||
|
||||
public function setHttpPath(string $path): DatabasesAction
|
||||
{
|
||||
switch (true) {
|
||||
|
||||
@@ -275,11 +275,11 @@ class Update extends Action
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, $totalOperations);
|
||||
->addMetric($this->getDatabasesOperationWriteMetric(), $totalOperations);
|
||||
|
||||
foreach ($databaseOperations as $sequence => $count) {
|
||||
$queueForStatsUsage->addMetric(
|
||||
str_replace('{databaseInternalId}', $sequence, METRIC_DATABASE_ID_OPERATIONS_WRITES),
|
||||
str_replace('{databaseInternalId}', $sequence, $this->getDatabasesIdOperationWriteMetric()),
|
||||
$count
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,42 @@ class Get extends Action
|
||||
return 'getDatabaseUsage';
|
||||
}
|
||||
|
||||
protected $databaseType = DATABASE_TYPE_LEGACY;
|
||||
|
||||
public function setHttpPath(string $path): Action
|
||||
{
|
||||
$this->databaseType = match (true) {
|
||||
str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB,
|
||||
default => DATABASE_TYPE_LEGACY,
|
||||
};
|
||||
|
||||
return parent::setHttpPath($path);
|
||||
}
|
||||
|
||||
protected function getMetrics(): array
|
||||
{
|
||||
$metrics = [
|
||||
METRIC_DATABASE_ID_COLLECTIONS,
|
||||
METRIC_DATABASE_ID_DOCUMENTS,
|
||||
METRIC_DATABASE_ID_STORAGE,
|
||||
METRIC_DATABASE_ID_OPERATIONS_READS,
|
||||
METRIC_DATABASE_ID_OPERATIONS_WRITES
|
||||
];
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === DATABASE_TYPE_TABLESDB) {
|
||||
return $metrics;
|
||||
}
|
||||
|
||||
return array_map(
|
||||
fn ($metric) => "{$this->databaseType}.{$metric}",
|
||||
$metrics
|
||||
);
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string
|
||||
{
|
||||
return UtopiaResponse::MODEL_USAGE_DATABASE;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -73,13 +109,10 @@ class Get extends Action
|
||||
$periods = Config::getParam('usage', []);
|
||||
$stats = $usage = [];
|
||||
$days = $periods[$range];
|
||||
$metrics = [
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_COLLECTIONS),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_DOCUMENTS),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_STORAGE),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_READS),
|
||||
str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_OPERATIONS_WRITES)
|
||||
];
|
||||
$metrics = array_map(
|
||||
fn ($metric) => str_replace('{databaseInternalId}', $database->getSequence(), $metric),
|
||||
$this->getMetrics()
|
||||
);
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
@@ -141,6 +174,6 @@ class Get extends Action
|
||||
'storage' => $usage[$metrics[2]]['data'],
|
||||
'databaseReads' => $usage[$metrics[3]]['data'],
|
||||
'databaseWrites' => $usage[$metrics[4]]['data'],
|
||||
]), UtopiaResponse::MODEL_USAGE_DATABASE);
|
||||
]), $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,42 @@ class XList extends Action
|
||||
return 'listDatabaseUsage';
|
||||
}
|
||||
|
||||
protected $databaseType = DATABASE_TYPE_LEGACY;
|
||||
|
||||
public function setHttpPath(string $path): Action
|
||||
{
|
||||
$this->databaseType = match (true) {
|
||||
str_contains($path, '/documentsdb') => DATABASE_TYPE_DOCUMENTSDB,
|
||||
default => DATABASE_TYPE_LEGACY,
|
||||
};
|
||||
|
||||
return parent::setHttpPath($path);
|
||||
}
|
||||
|
||||
protected function getMetrics(): array
|
||||
{
|
||||
$metrics = [
|
||||
METRIC_DATABASES,
|
||||
METRIC_COLLECTIONS,
|
||||
METRIC_DOCUMENTS,
|
||||
METRIC_DATABASES_STORAGE,
|
||||
METRIC_DATABASES_OPERATIONS_READS,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES,
|
||||
];
|
||||
if ($this->databaseType === DATABASE_TYPE_LEGACY || $this->databaseType === DATABASE_TYPE_TABLESDB) {
|
||||
return $metrics;
|
||||
}
|
||||
return array_map(
|
||||
fn ($metric) => "{$this->databaseType}.{$metric}",
|
||||
$metrics
|
||||
);
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string
|
||||
{
|
||||
return UtopiaResponse::MODEL_USAGE_DATABASES;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -65,14 +101,7 @@ class XList extends Action
|
||||
$periods = Config::getParam('usage', []);
|
||||
$stats = $usage = [];
|
||||
$days = $periods[$range];
|
||||
$metrics = [
|
||||
METRIC_DATABASES,
|
||||
METRIC_COLLECTIONS,
|
||||
METRIC_DOCUMENTS,
|
||||
METRIC_DATABASES_STORAGE,
|
||||
METRIC_DATABASES_OPERATIONS_READS,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES,
|
||||
];
|
||||
$metrics = $this->getMetrics();
|
||||
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
@@ -135,6 +164,6 @@ class XList extends Action
|
||||
'storage' => $usage[$metrics[3]]['data'],
|
||||
'databasesReads' => $usage[$metrics[4]]['data'],
|
||||
'databasesWrites' => $usage[$metrics[5]]['data'],
|
||||
]), UtopiaResponse::MODEL_USAGE_DATABASES);
|
||||
]), $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Validator\Permissions;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\JSON;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Create extends CollectionCreate
|
||||
@@ -59,6 +61,8 @@ class Create extends CollectionCreate
|
||||
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('documentSecurity', false, new Boolean(true), 'Enables configuring permissions for individual documents. A user needs one of document or collection level permissions to access a document. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('enabled', true, new Boolean(), 'Is collection enabled? When set to \'disabled\', users cannot access the collection but Server SDKs with and API key can still read and write to the collection. No data is lost when this is toggled.', true)
|
||||
->param('attributes', [], new ArrayList(new JSON(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of attribute definitions to create. Each attribute should contain: key (string), type (string: string, integer, float, boolean, datetime, relationship), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options.', true)
|
||||
->param('indexes', [], new ArrayList(new JSON(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of attribute keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional).', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('getDatabasesDB')
|
||||
|
||||
@@ -24,6 +24,11 @@ class Get extends CollectionUsageGet
|
||||
return UtopiaResponse::MODEL_USAGE_COLLECTION;
|
||||
}
|
||||
|
||||
protected function getMetric(): string
|
||||
{
|
||||
return METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS_DOCUMENTSDB;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
|
||||
@@ -19,6 +19,11 @@ class Get extends DatabaseUsageGet
|
||||
return 'getDocumentsDBUsage';
|
||||
}
|
||||
|
||||
public function getResponseModel(): string
|
||||
{
|
||||
return UtopiaResponse::MODEL_USAGE_DOCUMENTSDB;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -38,7 +43,7 @@ class Get extends DatabaseUsageGet
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: UtopiaResponse::MODEL_USAGE_DATABASE,
|
||||
model: UtopiaResponse::MODEL_USAGE_DOCUMENTSDB,
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON,
|
||||
|
||||
@@ -18,6 +18,11 @@ class XList extends DatabaseUsageXList
|
||||
return 'listDocumentsDBUsage';
|
||||
}
|
||||
|
||||
public function getResponseModel(): string
|
||||
{
|
||||
return UtopiaResponse::MODEL_USAGE_DOCUMENTSDBS;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
|
||||
@@ -13,7 +13,9 @@ use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Permissions;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\JSON;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
@@ -61,6 +63,8 @@ class Create extends CollectionCreate
|
||||
->param('permissions', null, new Nullable(new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE)), 'An array of permissions strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('rowSecurity', false, new Boolean(true), 'Enables configuring permissions for individual rows. A user needs one of row or table level permissions to access a row. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('enabled', true, new Boolean(), 'Is table enabled? When set to \'disabled\', users cannot access the table but Server SDKs with and API key can still read and write to the table. No data is lost when this is toggled.', true)
|
||||
->param('columns', [], new ArrayList(new JSON(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of column definitions to create. Each column should contain: key (string), type (string: string, integer, float, boolean, datetime, relationship), size (integer, required for string type), required (boolean, optional), default (mixed, optional), array (boolean, optional), and type-specific options.', true)
|
||||
->param('indexes', [], new ArrayList(new JSON(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of index definitions to create. Each index should contain: key (string), type (string: key, fulltext, unique, spatial), attributes (array of column keys), orders (array of ASC/DESC, optional), and lengths (array of integers, optional).', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('getDatabasesDB')
|
||||
|
||||
@@ -1107,10 +1107,6 @@ class Builds extends Action
|
||||
$resource = $dbForProject->updateDocument($resource->getCollection(), $resource->getId(), new Document(['latestDeploymentStatus' => $deployment->getAttribute('status', '')]));
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
if ($isVcsEnabled) {
|
||||
$this->runGitAction('ready', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform, $queueForRealtime);
|
||||
}
|
||||
@@ -1198,6 +1194,11 @@ class Builds extends Action
|
||||
Console::log('Deployment activated');
|
||||
}
|
||||
|
||||
// Send realtime event after updating the associated resource so that Console will have the resource's deployment details when re-fetching.
|
||||
$queueForRealtime
|
||||
->setPayload($deployment->getArrayCopy())
|
||||
->trigger();
|
||||
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
// VCS branch
|
||||
$branchName = $deployment->getAttribute('providerBranch');
|
||||
|
||||
@@ -286,6 +286,8 @@ class Migrations extends Action
|
||||
'disabledMetrics' => [
|
||||
METRIC_DATABASES_OPERATIONS_READS,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES,
|
||||
METRIC_DATABASES_OPERATIONS_READS_DOCUMENTSDB,
|
||||
METRIC_DATABASES_OPERATIONS_WRITES_DOCUMENTSDB,
|
||||
METRIC_NETWORK_REQUESTS,
|
||||
METRIC_NETWORK_INBOUND,
|
||||
METRIC_NETWORK_OUTBOUND,
|
||||
|
||||
@@ -123,7 +123,8 @@ class StatsResources extends Action
|
||||
]);
|
||||
|
||||
|
||||
$databases = $dbForProject->count('databases');
|
||||
$databases = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_LEGACY, DATABASE_TYPE_TABLESDB])]);
|
||||
$documentsdb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB])]);
|
||||
$buckets = $dbForProject->count('buckets');
|
||||
$users = $dbForProject->count('users');
|
||||
|
||||
@@ -158,6 +159,7 @@ class StatsResources extends Action
|
||||
|
||||
$metrics = [
|
||||
METRIC_DATABASES => $databases,
|
||||
METRIC_DATABASES_DOCUMENTSDB => $documentsdb,
|
||||
METRIC_BUCKETS => $buckets,
|
||||
METRIC_USERS => $users,
|
||||
METRIC_FUNCTIONS => $functions,
|
||||
@@ -259,48 +261,83 @@ class StatsResources extends Action
|
||||
{
|
||||
$totalCollections = 0;
|
||||
$totalDocuments = 0;
|
||||
|
||||
$totalDatabaseStorage = 0;
|
||||
|
||||
$this->foreachDocument($dbForProject, 'databases', [], function ($database) use ($dbForProject, $getDatabasesDB, $region, &$totalCollections, &$totalDocuments, &$totalDatabaseStorage) {
|
||||
// documentsdb
|
||||
$totalCollectionsDocumentsdb = 0;
|
||||
$totalDocumentsDocumentsdb = 0;
|
||||
$totalDatabaseStorageDocumentsdb = 0;
|
||||
|
||||
|
||||
$this->foreachDocument($dbForProject, 'databases', [], function ($database) use ($dbForProject, $getDatabasesDB, $region, &$totalCollections, &$totalDocuments, &$totalDatabaseStorage, &$totalCollectionsDocumentsdb, &$totalDocumentsDocumentsdb, &$totalDatabaseStorageDocumentsdb) {
|
||||
$dbForDatabases = $getDatabasesDB($database);
|
||||
$collections = $dbForProject->count('database_' . $database->getSequence());
|
||||
|
||||
$metric = str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_COLLECTIONS);
|
||||
$databaseType = $database->getAttribute('type');
|
||||
$collectionsMetric = METRIC_DATABASE_ID_COLLECTIONS;
|
||||
if (!empty($databaseType) && $databaseType !== DATABASE_TYPE_LEGACY && $databaseType !== DATABASE_TYPE_TABLESDB) {
|
||||
$collectionsMetric = $databaseType . '.' . $collectionsMetric;
|
||||
}
|
||||
$metric = str_replace('{databaseInternalId}', $database->getSequence(), $collectionsMetric);
|
||||
$this->createStatsDocuments($region, $metric, $collections);
|
||||
|
||||
[$documents, $storage] = $this->countForCollections($dbForProject, $dbForDatabases, $database, $region);
|
||||
|
||||
$totalDatabaseStorage += $storage;
|
||||
$totalDocuments += $documents;
|
||||
$totalCollections += $collections;
|
||||
switch ($database->getAttribute('type')) {
|
||||
case DATABASE_TYPE_DOCUMENTSDB:
|
||||
$totalDatabaseStorageDocumentsdb += $storage;
|
||||
$totalDocumentsDocumentsdb += $documents;
|
||||
$totalCollectionsDocumentsdb += $collections;
|
||||
break;
|
||||
default:
|
||||
$totalDatabaseStorage += $storage;
|
||||
$totalDocuments += $documents;
|
||||
$totalCollections += $collections;
|
||||
}
|
||||
});
|
||||
|
||||
$this->createStatsDocuments($region, METRIC_COLLECTIONS, $totalCollections);
|
||||
$this->createStatsDocuments($region, METRIC_DOCUMENTS, $totalDocuments);
|
||||
$this->createStatsDocuments($region, METRIC_DATABASES_STORAGE, $totalDatabaseStorage);
|
||||
|
||||
$this->createStatsDocuments($region, METRIC_COLLECTIONS_DOCUMENTSDB, $totalCollectionsDocumentsdb);
|
||||
$this->createStatsDocuments($region, METRIC_DOCUMENTS_DOCUMENTSDB, $totalDocumentsDocumentsdb);
|
||||
$this->createStatsDocuments($region, METRIC_DATABASES_STORAGE_DOCUMENTSDB, $totalDatabaseStorageDocumentsdb);
|
||||
}
|
||||
protected function countForCollections(Database $dbForProject, Database $dbForDatabases, Document $database, string $region): array
|
||||
{
|
||||
$databaseDocuments = 0;
|
||||
$databaseStorage = 0;
|
||||
$this->foreachDocument($dbForProject, 'database_' . $database->getSequence(), [], function ($collection) use ($dbForProject, $dbForDatabases, $database, $region, &$databaseStorage, &$databaseDocuments) {
|
||||
$databaseType = $database->getAttribute('type');
|
||||
$databaseIdCollectionIdDocumentsMetric = METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS;
|
||||
$databaseIdCollectionIdStorageMetric = METRIC_DATABASE_ID_COLLECTION_ID_STORAGE;
|
||||
$databaseIdDocumentsMetric = METRIC_DATABASE_ID_DOCUMENTS;
|
||||
$databaseIdStorageMetric = METRIC_DATABASE_ID_STORAGE;
|
||||
|
||||
if ($databaseType !== DATABASE_TYPE_LEGACY && $databaseType !== DATABASE_TYPE_TABLESDB) {
|
||||
$databaseIdCollectionIdDocumentsMetric = $databaseType . '.' . $databaseIdCollectionIdDocumentsMetric;
|
||||
$databaseIdCollectionIdStorageMetric = $databaseType . '.' . $databaseIdCollectionIdStorageMetric;
|
||||
$databaseIdDocumentsMetric = $databaseType . '.' . $databaseIdDocumentsMetric;
|
||||
$databaseIdStorageMetric = $databaseType . '.' . $databaseIdStorageMetric;
|
||||
}
|
||||
|
||||
$this->foreachDocument($dbForProject, 'database_' . $database->getSequence(), [], function ($collection) use ($dbForProject, $dbForDatabases, $database, $region, &$databaseStorage, &$databaseDocuments, $databaseIdCollectionIdDocumentsMetric, $databaseIdCollectionIdStorageMetric) {
|
||||
$documents = $dbForDatabases->count('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
$metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS);
|
||||
$metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], $databaseIdCollectionIdDocumentsMetric);
|
||||
$this->createStatsDocuments($region, $metric, $documents);
|
||||
$databaseDocuments += $documents;
|
||||
|
||||
$collectionStorage = $dbForDatabases->getSizeOfCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
$metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], METRIC_DATABASE_ID_COLLECTION_ID_STORAGE);
|
||||
$metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], $databaseIdCollectionIdStorageMetric);
|
||||
$this->createStatsDocuments($region, $metric, $collectionStorage);
|
||||
$databaseStorage += $collectionStorage;
|
||||
|
||||
});
|
||||
|
||||
$metric = str_replace(['{databaseInternalId}'], [$database->getSequence()], METRIC_DATABASE_ID_DOCUMENTS);
|
||||
$metric = str_replace(['{databaseInternalId}'], [$database->getSequence()], $databaseIdDocumentsMetric);
|
||||
$this->createStatsDocuments($region, $metric, $databaseDocuments);
|
||||
|
||||
$metric = str_replace(['{databaseInternalId}'], [$database->getSequence()], METRIC_DATABASE_ID_STORAGE);
|
||||
$metric = str_replace(['{databaseInternalId}'], [$database->getSequence()], $databaseIdStorageMetric);
|
||||
$this->createStatsDocuments($region, $metric, $databaseStorage);
|
||||
|
||||
return [$databaseDocuments, $databaseStorage];
|
||||
|
||||
@@ -47,6 +47,7 @@ class StatsUsage extends Action
|
||||
*/
|
||||
protected array $skipBaseMetrics = [
|
||||
METRIC_DATABASES => true,
|
||||
METRIC_DATABASES_DOCUMENTSDB => true,
|
||||
METRIC_BUCKETS => true,
|
||||
METRIC_USERS => true,
|
||||
METRIC_FUNCTIONS => true,
|
||||
@@ -85,6 +86,12 @@ class StatsUsage extends Action
|
||||
'.databases.storage'
|
||||
];
|
||||
|
||||
public const DATABASE_PREFIXES = [
|
||||
DATABASE_TYPE_LEGACY,
|
||||
DATABASE_TYPE_TABLESDB,
|
||||
DATABASE_TYPE_DOCUMENTSDB,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var callable(): Database
|
||||
*/
|
||||
@@ -146,6 +153,11 @@ class StatsUsage extends Action
|
||||
$aggregationInterval = (int) System::getEnv('_APP_USAGE_AGGREGATION_INTERVAL', '20');
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
$projectId = $project->getSequence();
|
||||
|
||||
// Get database type from context
|
||||
$databaseContext = $payload['context']['database'] ?? null;
|
||||
$databaseType = $databaseContext ? (new Document($databaseContext))->getAttribute('type', '') : '';
|
||||
|
||||
foreach ($payload['reduce'] ?? [] as $document) {
|
||||
if (empty($document)) {
|
||||
continue;
|
||||
@@ -155,7 +167,8 @@ class StatsUsage extends Action
|
||||
project: $project,
|
||||
document: new Document($document),
|
||||
metrics: $payload['metrics'],
|
||||
getProjectDB: $getProjectDB
|
||||
getProjectDB: $getProjectDB,
|
||||
databaseType: $databaseType
|
||||
);
|
||||
}
|
||||
|
||||
@@ -193,9 +206,10 @@ class StatsUsage extends Action
|
||||
* @param Document $document
|
||||
* @param array $metrics
|
||||
* @param callable(): Database $getProjectDB
|
||||
* @param string $databaseType Database type from context
|
||||
* @return void
|
||||
*/
|
||||
protected function reduce(Document $project, Document $document, array &$metrics, callable $getProjectDB): void
|
||||
protected function reduce(Document $project, Document $document, array &$metrics, callable $getProjectDB, string $databaseType = ''): void
|
||||
{
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
@@ -211,38 +225,48 @@ class StatsUsage extends Action
|
||||
}
|
||||
break;
|
||||
case $document->getCollection() === 'databases': // databases
|
||||
$collections = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getSequence(), METRIC_DATABASE_ID_COLLECTIONS)));
|
||||
$documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getSequence(), METRIC_DATABASE_ID_DOCUMENTS)));
|
||||
$databaseCollectionsMetric = implode('.', array_filter([$databaseType,METRIC_COLLECTIONS]));
|
||||
$databaseDocumentsMetric = implode('.', array_filter([$databaseType,METRIC_DOCUMENTS]));
|
||||
|
||||
$databaseIdCollectionsMetric = implode('.', array_filter([$databaseType,METRIC_DATABASE_ID_COLLECTIONS]));
|
||||
$databaseIdDocumentsMetric = implode('.', array_filter([$databaseType,METRIC_DATABASE_ID_DOCUMENTS]));
|
||||
|
||||
$collections = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getSequence(), $databaseIdCollectionsMetric)));
|
||||
$documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace('{databaseInternalId}', $document->getSequence(), $databaseIdDocumentsMetric)));
|
||||
if (!empty($collections['value'])) {
|
||||
$metrics[] = [
|
||||
'key' => METRIC_COLLECTIONS,
|
||||
'key' => $databaseCollectionsMetric,
|
||||
'value' => ($collections['value'] * -1),
|
||||
];
|
||||
}
|
||||
|
||||
if (!empty($documents['value'])) {
|
||||
$metrics[] = [
|
||||
'key' => METRIC_DOCUMENTS,
|
||||
'key' => $databaseDocumentsMetric,
|
||||
'value' => ($documents['value'] * -1),
|
||||
];
|
||||
}
|
||||
break;
|
||||
case str_starts_with($document->getCollection(), 'database_') && !str_contains($document->getCollection(), 'collection'): //collections
|
||||
$databaseDocumentsMetric = implode('.', array_filter([$databaseType,METRIC_DOCUMENTS]));
|
||||
$databaseIdCollectionIdDocumentsMetric = implode('.', array_filter([$databaseType,METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS]));
|
||||
$databaseIdDocumentsMetric = implode('.', array_filter([$databaseType,METRIC_DATABASE_ID_DOCUMENTS]));
|
||||
|
||||
$parts = explode('_', $document->getCollection());
|
||||
$databaseInternalId = $parts[1] ?? 0;
|
||||
$documents = $dbForProject->getDocument('stats', md5(self::INFINITY_PERIOD . str_replace(
|
||||
['{databaseInternalId}', '{collectionInternalId}'],
|
||||
[$databaseInternalId, $document->getSequence()],
|
||||
METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS
|
||||
$databaseIdCollectionIdDocumentsMetric
|
||||
)));
|
||||
|
||||
if (!empty($documents['value'])) {
|
||||
$metrics[] = [
|
||||
'key' => METRIC_DOCUMENTS,
|
||||
'key' => $databaseDocumentsMetric,
|
||||
'value' => ($documents['value'] * -1),
|
||||
];
|
||||
$metrics[] = [
|
||||
'key' => str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS),
|
||||
'key' => str_replace('{databaseInternalId}', $databaseInternalId, $databaseIdDocumentsMetric),
|
||||
'value' => ($documents['value'] * -1),
|
||||
];
|
||||
}
|
||||
@@ -473,8 +497,11 @@ class StatsUsage extends Action
|
||||
if (array_key_exists($stat->getAttribute('metric'), $this->skipBaseMetrics)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->skipParentIdMetrics as $skipMetric) {
|
||||
if (str_ends_with($stat->getAttribute('metric'), $skipMetric)) {
|
||||
$metricParts = explode('.', $stat->getAttribute('metric'));
|
||||
$metric = implode('.', in_array($metricParts[0], self::DATABASE_PREFIXES) ? array_slice($metricParts, 1) : $metricParts);
|
||||
if (str_ends_with($metric, $metric)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +171,12 @@ abstract class Format
|
||||
return 'CreditCard';
|
||||
case 'getFlag':
|
||||
return 'Flag';
|
||||
case 'getScreenshot':
|
||||
switch ($param) {
|
||||
case 'permissions':
|
||||
return 'BrowserPermission';
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'databases':
|
||||
|
||||
@@ -19,7 +19,6 @@ use Utopia\Validator;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class OpenAPI3 extends Format
|
||||
{
|
||||
@@ -440,6 +439,7 @@ class OpenAPI3 extends Format
|
||||
$subclass = \get_class($validator->getValidator());
|
||||
switch ($subclass) {
|
||||
case 'Appwrite\Utopia\Database\Validator\Operation':
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
$class = $subclass;
|
||||
break;
|
||||
}
|
||||
@@ -449,23 +449,23 @@ class OpenAPI3 extends Format
|
||||
case 'Utopia\Database\Validator\UID':
|
||||
case 'Utopia\Validator\Text':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
break;
|
||||
case 'Utopia\Validator\Boolean':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = false;
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: false;
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\CustomId':
|
||||
if ($sdk->getType() === MethodType::UPLOAD) {
|
||||
$node['schema']['x-upload-id'] = true;
|
||||
}
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
break;
|
||||
case 'Utopia\Database\Validator\DatetimeValidator':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['format'] = 'datetime';
|
||||
$node['schema']['x-example'] = Model::TYPE_DATETIME_EXAMPLE;
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: Model::TYPE_DATETIME_EXAMPLE;
|
||||
break;
|
||||
case 'Utopia\Database\Validator\Spatial':
|
||||
/** @var Spatial $validator */
|
||||
@@ -475,7 +475,7 @@ class OpenAPI3 extends Format
|
||||
['type' => 'array']
|
||||
]
|
||||
];
|
||||
$node['schema']['x-example'] = match ($validator->getSpatialType()) {
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: match ($validator->getSpatialType()) {
|
||||
Database::VAR_POINT => '[1, 2]',
|
||||
Database::VAR_LINESTRING => '[[1, 2], [3, 4], [5, 6]]',
|
||||
Database::VAR_POLYGON => '[[[1, 2], [3, 4], [5, 6], [1, 2]]]',
|
||||
@@ -484,14 +484,14 @@ class OpenAPI3 extends Format
|
||||
case 'Appwrite\Network\Validator\Email':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['format'] = 'email';
|
||||
$node['schema']['x-example'] = 'email@example.com';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
case 'Utopia\Validator\URL':
|
||||
case 'Appwrite\Network\Validator\Redirect':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['format'] = 'url';
|
||||
$node['schema']['x-example'] = 'https://example.com';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\JSON':
|
||||
case 'Utopia\Validator\Mock':
|
||||
@@ -511,6 +511,9 @@ class OpenAPI3 extends Format
|
||||
$node['schema']['items'] = [
|
||||
'type' => $validator->getValidator()->getType(),
|
||||
];
|
||||
if (!empty($param['example'])) {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Base':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Columns':
|
||||
@@ -551,73 +554,115 @@ class OpenAPI3 extends Format
|
||||
$node['schema']['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
$node['schema']['x-example'] = '["' . Permission::read(Role::any()) . '"]';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: '["' . Permission::read(Role::any()) . '"]';
|
||||
break;
|
||||
case 'Utopia\Database\Validator\Roles':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
$node['schema']['x-example'] = '["' . Role::any()->toString() . '"]';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: '["' . Role::any()->toString() . '"]';
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Password':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['format'] = 'password';
|
||||
$node['schema']['x-example'] = 'password';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: 'password';
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Phone':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['format'] = 'phone';
|
||||
$node['schema']['x-example'] = '+12065550100'; // In the US, 555 is reserved like example.com
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: '+12065550100'; // In the US, 555 is reserved like example.com
|
||||
break;
|
||||
case 'Utopia\Validator\Range':
|
||||
/** @var Range $validator */
|
||||
$node['schema']['type'] = $validator->getType() === Validator::TYPE_FLOAT ? 'number' : $validator->getType();
|
||||
$node['schema']['format'] = $validator->getType() == Validator::TYPE_INTEGER ? 'int32' : 'float';
|
||||
$node['schema']['x-example'] = $validator->getMin();
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: $validator->getMin();
|
||||
break;
|
||||
case 'Utopia\Validator\Integer':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['format'] = 'int32';
|
||||
if (!empty($param['example'])) {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\Numeric':
|
||||
case 'Utopia\Validator\FloatValidator':
|
||||
$node['schema']['type'] = 'number';
|
||||
$node['schema']['format'] = 'float';
|
||||
if (!empty($param['example'])) {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\Length':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
if (!empty($param['example'])) {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
/** @var WhiteList $validator */
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = $validator->getList()[0];
|
||||
if ($array) {
|
||||
$validator = $validator->getValidator();
|
||||
|
||||
// Iterate from the blackList. If it matches with the current one, then it is a blackList
|
||||
// Do not add the enum
|
||||
$allowed = true;
|
||||
foreach ($this->enumBlacklist as $blacklist) {
|
||||
if (
|
||||
$blacklist['namespace'] == $sdk->getNamespace()
|
||||
&& $blacklist['method'] == $methodName
|
||||
&& $blacklist['parameter'] == $name
|
||||
) {
|
||||
$allowed = false;
|
||||
break;
|
||||
$node['schema']['type'] = 'array';
|
||||
$node['schema']['items'] = [
|
||||
'type' => $validator->getType(),
|
||||
];
|
||||
if (!empty($param['example'])) {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
|
||||
// Iterate from the blackList. If it matches with the current one, then it is a blackList
|
||||
// Do not add the enum
|
||||
$allowed = true;
|
||||
foreach ($this->enumBlacklist as $blacklist) {
|
||||
if (
|
||||
$blacklist['namespace'] == $sdk->getNamespace()
|
||||
&& $blacklist['method'] == $methodName
|
||||
&& $blacklist['parameter'] == $name
|
||||
) {
|
||||
$allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($allowed && $validator->getType() === 'string') {
|
||||
$node['schema']['items']['enum'] = \array_values($validator->getList());
|
||||
$node['schema']['items']['x-enum-name'] = $this->getRequestEnumName($sdk->getNamespace() ?? '', $methodName, $name);
|
||||
$node['schema']['items']['x-enum-keys'] = $this->getRequestEnumKeys($sdk->getNamespace() ?? '', $methodName, $name);
|
||||
}
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['schema']['items']['format'] = 'int32';
|
||||
}
|
||||
} else {
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: $validator->getList()[0];
|
||||
|
||||
// Iterate from the blackList. If it matches with the current one, then it is a blackList
|
||||
// Do not add the enum
|
||||
$allowed = true;
|
||||
foreach ($this->enumBlacklist as $blacklist) {
|
||||
if (
|
||||
$blacklist['namespace'] == $sdk->getNamespace()
|
||||
&& $blacklist['method'] == $methodName
|
||||
&& $blacklist['parameter'] == $name
|
||||
) {
|
||||
$allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($allowed && $validator->getType() === 'string') {
|
||||
$node['schema']['enum'] = \array_values($validator->getList());
|
||||
$node['schema']['x-enum-name'] = $this->getRequestEnumName($sdk->getNamespace() ?? '', $methodName, $name);
|
||||
$node['schema']['x-enum-keys'] = $this->getRequestEnumKeys($sdk->getNamespace() ?? '', $methodName, $name);
|
||||
}
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['format'] = 'int32';
|
||||
}
|
||||
}
|
||||
if ($allowed && $validator->getType() === 'string') {
|
||||
$node['schema']['enum'] = $validator->getList();
|
||||
$node['schema']['x-enum-name'] = $this->getRequestEnumName($sdk->getNamespace() ?? '', $methodName, $name);
|
||||
$node['schema']['x-enum-keys'] = $this->getRequestEnumKeys($sdk->getNamespace() ?? '', $methodName, $name);
|
||||
}
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['format'] = 'int32';
|
||||
}
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\CompoundUID':
|
||||
$node['schema']['type'] = $validator->getType();
|
||||
$node['schema']['x-example'] = '<ID1:ID2>';
|
||||
$node['schema']['x-example'] = ($param['example'] ?? '') ?: '<ID1:ID2>';
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\Operation':
|
||||
if ($array) {
|
||||
@@ -633,22 +678,29 @@ class OpenAPI3 extends Format
|
||||
} else {
|
||||
$node['schema']['type'] = 'object';
|
||||
}
|
||||
$example = [
|
||||
'action' => 'create',
|
||||
'databaseId' => '<DATABASE_ID>',
|
||||
$collectionIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($collectionIdKey)).'>',
|
||||
$documentIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($documentIdKey)).'>',
|
||||
'data' => [
|
||||
'name' => 'Walter O\'Brien',
|
||||
],
|
||||
];
|
||||
if ($array) {
|
||||
$example = [$example];
|
||||
if (empty($param['example'])) {
|
||||
$example = [
|
||||
'action' => 'create',
|
||||
'databaseId' => '<DATABASE_ID>',
|
||||
$collectionIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($collectionIdKey)).'>',
|
||||
$documentIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($documentIdKey)).'>',
|
||||
'data' => [
|
||||
'name' => 'Walter O\'Brien',
|
||||
],
|
||||
];
|
||||
if ($array) {
|
||||
$example = [$example];
|
||||
}
|
||||
$node['schema']['x-example'] = \str_replace("\n", "\n\t", \json_encode($example, JSON_PRETTY_PRINT));
|
||||
} else {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
$node['schema']['x-example'] = \str_replace("\n", "\n\t", \json_encode($example, JSON_PRETTY_PRINT));
|
||||
break;
|
||||
default:
|
||||
$node['schema']['type'] = 'string';
|
||||
if (!empty($param['example'])) {
|
||||
$node['schema']['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -853,13 +905,13 @@ class OpenAPI3 extends Format
|
||||
}
|
||||
if ($rule['type'] === 'enum' && !empty($rule['enum'])) {
|
||||
if ($rule['array']) {
|
||||
$output['components']['schemas'][$model->getType()]['properties'][$name]['items']['enum'] = $rule['enum'];
|
||||
$output['components']['schemas'][$model->getType()]['properties'][$name]['items']['enum'] = \array_values($rule['enum']);
|
||||
$enumName = $this->getResponseEnumName($model->getType(), $name);
|
||||
if ($enumName) {
|
||||
$output['components']['schemas'][$model->getType()]['properties'][$name]['items']['x-enum-name'] = $enumName;
|
||||
}
|
||||
} else {
|
||||
$output['components']['schemas'][$model->getType()]['properties'][$name]['enum'] = $rule['enum'];
|
||||
$output['components']['schemas'][$model->getType()]['properties'][$name]['enum'] = \array_values($rule['enum']);
|
||||
$enumName = $this->getResponseEnumName($model->getType(), $name);
|
||||
if ($enumName) {
|
||||
$output['components']['schemas'][$model->getType()]['properties'][$name]['x-enum-name'] = $enumName;
|
||||
|
||||
@@ -20,7 +20,6 @@ use Utopia\Validator;
|
||||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class Swagger2 extends Format
|
||||
{
|
||||
@@ -445,6 +444,7 @@ class Swagger2 extends Format
|
||||
$subclass = \get_class($validator->getValidator());
|
||||
switch ($subclass) {
|
||||
case 'Appwrite\Utopia\Database\Validator\Operation':
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
$class = $subclass;
|
||||
break;
|
||||
}
|
||||
@@ -454,23 +454,23 @@ class Swagger2 extends Format
|
||||
case 'Utopia\Validator\Text':
|
||||
case 'Utopia\Database\Validator\UID':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
break;
|
||||
case 'Utopia\Validator\Boolean':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = false;
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: false;
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\CustomId':
|
||||
if ($sdk->getType() === MethodType::UPLOAD) {
|
||||
$node['x-upload-id'] = true;
|
||||
}
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: '<' . \strtoupper(Template::fromCamelCaseToSnake($node['name'])) . '>';
|
||||
break;
|
||||
case 'Utopia\Database\Validator\DatetimeValidator':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['format'] = 'datetime';
|
||||
$node['x-example'] = Model::TYPE_DATETIME_EXAMPLE;
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: Model::TYPE_DATETIME_EXAMPLE;
|
||||
break;
|
||||
case 'Utopia\Database\Validator\Spatial':
|
||||
/** @var Spatial $validator */
|
||||
@@ -480,7 +480,7 @@ class Swagger2 extends Format
|
||||
['type' => 'array']
|
||||
]
|
||||
];
|
||||
$node['x-example'] = match ($validator->getSpatialType()) {
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: match ($validator->getSpatialType()) {
|
||||
Database::VAR_POINT => '[1, 2]',
|
||||
Database::VAR_LINESTRING => '[[1, 2], [3, 4], [5, 6]]',
|
||||
Database::VAR_POLYGON => '[[[1, 2], [3, 4], [5, 6], [1, 2]]]',
|
||||
@@ -489,14 +489,14 @@ class Swagger2 extends Format
|
||||
case 'Appwrite\Network\Validator\Email':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['format'] = 'email';
|
||||
$node['x-example'] = 'email@example.com';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: 'email@example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\Host':
|
||||
case 'Utopia\Validator\URL':
|
||||
case 'Appwrite\Network\Validator\Redirect':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['format'] = 'url';
|
||||
$node['x-example'] = 'https://example.com';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: 'https://example.com';
|
||||
break;
|
||||
case 'Utopia\Validator\ArrayList':
|
||||
/** @var ArrayList $validator */
|
||||
@@ -505,6 +505,9 @@ class Swagger2 extends Format
|
||||
$node['items'] = [
|
||||
'type' => $validator->getValidator()->getType(),
|
||||
];
|
||||
if (!empty($param['example'])) {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\JSON':
|
||||
case 'Utopia\Validator\Mock':
|
||||
@@ -539,7 +542,7 @@ class Swagger2 extends Format
|
||||
$node['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
$node['x-example'] = '["' . Permission::read(Role::any()) . '"]';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: '["' . Permission::read(Role::any()) . '"]';
|
||||
break;
|
||||
case 'Utopia\Database\Validator\Roles':
|
||||
$node['type'] = $validator->getType();
|
||||
@@ -547,61 +550,99 @@ class Swagger2 extends Format
|
||||
$node['items'] = [
|
||||
'type' => 'string',
|
||||
];
|
||||
$node['x-example'] = '["' . Role::any()->toString() . '"]';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: '["' . Role::any()->toString() . '"]';
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Password':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['format'] = 'password';
|
||||
$node['x-example'] = 'password';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: 'password';
|
||||
break;
|
||||
case 'Appwrite\Auth\Validator\Phone':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['format'] = 'phone';
|
||||
$node['x-example'] = '+12065550100';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: '+12065550100';
|
||||
break;
|
||||
case 'Utopia\Validator\Range':
|
||||
/** @var Range $validator */
|
||||
$node['type'] = $validator->getType() === Validator::TYPE_FLOAT ? 'number' : $validator->getType();
|
||||
$node['format'] = $validator->getType() == Validator::TYPE_INTEGER ? 'int32' : 'float';
|
||||
$node['x-example'] = $validator->getMin();
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: $validator->getMin();
|
||||
break;
|
||||
case 'Utopia\Validator\Integer':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['format'] = 'int32';
|
||||
if (!empty($param['example'])) {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\Numeric':
|
||||
case 'Utopia\Validator\FloatValidator':
|
||||
$node['type'] = 'number';
|
||||
$node['format'] = 'float';
|
||||
if (!empty($param['example'])) {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\Length':
|
||||
$node['type'] = $validator->getType();
|
||||
if (!empty($param['example'])) {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
case 'Utopia\Validator\WhiteList':
|
||||
/** @var WhiteList $validator */
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = $validator->getList()[0];
|
||||
if ($array) {
|
||||
$validator = $validator->getValidator();
|
||||
|
||||
// Iterate the blackList. If it matches with the current one, then it is blackListed
|
||||
$allowed = true;
|
||||
foreach ($this->enumBlacklist as $blacklist) {
|
||||
if ($blacklist['namespace'] == $namespace && $blacklist['method'] == $methodName && $blacklist['parameter'] == $name) {
|
||||
$allowed = false;
|
||||
break;
|
||||
$node['type'] = 'array';
|
||||
$node['collectionFormat'] = 'multi';
|
||||
$node['items'] = [
|
||||
'type' => $validator->getType(),
|
||||
];
|
||||
if (!empty($param['example'])) {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
|
||||
// Iterate the blackList. If it matches with the current one, then it is blackListed
|
||||
$allowed = true;
|
||||
foreach ($this->enumBlacklist as $blacklist) {
|
||||
if ($blacklist['namespace'] == $namespace && $blacklist['method'] == $methodName && $blacklist['parameter'] == $name) {
|
||||
$allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($allowed && $validator->getType() === 'string') {
|
||||
$node['items']['enum'] = \array_values($validator->getList());
|
||||
$node['items']['x-enum-name'] = $this->getRequestEnumName($namespace, $methodName, $name);
|
||||
$node['items']['x-enum-keys'] = $this->getRequestEnumKeys($namespace, $methodName, $name);
|
||||
}
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['items']['format'] = 'int32';
|
||||
}
|
||||
} else {
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: $validator->getList()[0];
|
||||
|
||||
// Iterate the blackList. If it matches with the current one, then it is blackListed
|
||||
$allowed = true;
|
||||
foreach ($this->enumBlacklist as $blacklist) {
|
||||
if ($blacklist['namespace'] == $namespace && $blacklist['method'] == $methodName && $blacklist['parameter'] == $name) {
|
||||
$allowed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($allowed && $validator->getType() === 'string') {
|
||||
$node['enum'] = \array_values($validator->getList());
|
||||
$node['x-enum-name'] = $this->getRequestEnumName($namespace, $methodName, $name);
|
||||
$node['x-enum-keys'] = $this->getRequestEnumKeys($namespace, $methodName, $name);
|
||||
}
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['format'] = 'int32';
|
||||
}
|
||||
}
|
||||
if ($allowed && $validator->getType() === 'string') {
|
||||
$node['enum'] = $validator->getList();
|
||||
$node['x-enum-name'] = $this->getRequestEnumName($namespace, $methodName, $name);
|
||||
$node['x-enum-keys'] = $this->getRequestEnumKeys($namespace, $methodName, $name);
|
||||
}
|
||||
if ($validator->getType() === 'integer') {
|
||||
$node['format'] = 'int32';
|
||||
}
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\CompoundUID':
|
||||
$node['type'] = $validator->getType();
|
||||
$node['x-example'] = '<ID1:ID2>';
|
||||
$node['x-example'] = ($param['example'] ?? '') ?: '<ID1:ID2>';
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\Operation':
|
||||
if ($array) {
|
||||
@@ -618,22 +659,29 @@ class Swagger2 extends Format
|
||||
} else {
|
||||
$node['type'] = 'object';
|
||||
}
|
||||
$example = [
|
||||
'action' => 'create',
|
||||
'databaseId' => '<DATABASE_ID>',
|
||||
$collectionIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($collectionIdKey)).'>',
|
||||
$documentIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($documentIdKey)).'>',
|
||||
'data' => [
|
||||
'name' => 'Walter O\'Brien',
|
||||
],
|
||||
];
|
||||
if ($array) {
|
||||
$example = [$example];
|
||||
if (empty($param['example'])) {
|
||||
$example = [
|
||||
'action' => 'create',
|
||||
'databaseId' => '<DATABASE_ID>',
|
||||
$collectionIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($collectionIdKey)).'>',
|
||||
$documentIdKey => '<'.\strtoupper(Template::fromCamelCaseToSnake($documentIdKey)).'>',
|
||||
'data' => [
|
||||
'name' => 'Walter O\'Brien',
|
||||
],
|
||||
];
|
||||
if ($array) {
|
||||
$example = [$example];
|
||||
}
|
||||
$node['x-example'] = \str_replace("\n", "\n\t", \json_encode($example, JSON_PRETTY_PRINT));
|
||||
} else {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
$node['x-example'] = \str_replace("\n", "\n\t", \json_encode($example, JSON_PRETTY_PRINT));
|
||||
break;
|
||||
default:
|
||||
$node['type'] = 'string';
|
||||
if (!empty($param['example'])) {
|
||||
$node['x-example'] = $param['example'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -853,13 +901,13 @@ class Swagger2 extends Format
|
||||
}
|
||||
if ($rule['type'] === 'enum' && !empty($rule['enum'])) {
|
||||
if ($rule['array']) {
|
||||
$output['definitions'][$model->getType()]['properties'][$name]['items']['enum'] = $rule['enum'];
|
||||
$output['definitions'][$model->getType()]['properties'][$name]['items']['enum'] = \array_values($rule['enum']);
|
||||
$enumName = $this->getResponseEnumName($model->getType(), $name);
|
||||
if ($enumName) {
|
||||
$output['definitions'][$model->getType()]['properties'][$name]['items']['x-enum-name'] = $enumName;
|
||||
}
|
||||
} else {
|
||||
$output['definitions'][$model->getType()]['properties'][$name]['enum'] = $rule['enum'];
|
||||
$output['definitions'][$model->getType()]['properties'][$name]['enum'] = \array_values($rule['enum']);
|
||||
$enumName = $this->getResponseEnumName($model->getType(), $name);
|
||||
if ($enumName) {
|
||||
$output['definitions'][$model->getType()]['properties'][$name]['x-enum-name'] = $enumName;
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator;
|
||||
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Validator;
|
||||
use Utopia\Validator\Email;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
|
||||
class Attributes extends Validator
|
||||
{
|
||||
protected int $maxAttributes;
|
||||
protected string $message = 'Invalid attributes';
|
||||
|
||||
/**
|
||||
* @var array<string> Supported attribute types
|
||||
*/
|
||||
protected array $supportedTypes = [
|
||||
Database::VAR_STRING,
|
||||
Database::VAR_INTEGER,
|
||||
Database::VAR_FLOAT,
|
||||
Database::VAR_BOOLEAN,
|
||||
Database::VAR_DATETIME,
|
||||
Database::VAR_POINT,
|
||||
Database::VAR_LINESTRING,
|
||||
Database::VAR_POLYGON,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array<string> Supported formats for string attributes
|
||||
*/
|
||||
protected array $supportedFormats = [
|
||||
'',
|
||||
APP_DATABASE_ATTRIBUTE_EMAIL,
|
||||
APP_DATABASE_ATTRIBUTE_ENUM,
|
||||
APP_DATABASE_ATTRIBUTE_IP,
|
||||
APP_DATABASE_ATTRIBUTE_URL,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param int $maxAttributes Maximum number of attributes allowed
|
||||
* @param bool $supportForSpatialAttributes Whether DB supports spatial attributes
|
||||
* @param bool $supportForSpatialAttributes Whether DB supports attributes or not
|
||||
*/
|
||||
public function __construct(
|
||||
int $maxAttributes = APP_LIMIT_ARRAY_PARAMS_SIZE,
|
||||
protected bool $supportForSpatialAttributes = true,
|
||||
protected bool $supportForAttributes = true
|
||||
) {
|
||||
$this->maxAttributes = $maxAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Description
|
||||
*
|
||||
* Returns validator description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($value): bool
|
||||
{
|
||||
if (!\is_array($value)) {
|
||||
$this->message = 'Attributes must be an array';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (\count($value) && !$this->supportForAttributes) {
|
||||
$this->message = "Attributes are not supported by the current database";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (\count($value) > $this->maxAttributes) {
|
||||
$this->message = 'Maximum of ' . $this->maxAttributes . ' attributes allowed';
|
||||
return false;
|
||||
}
|
||||
|
||||
$keyValidator = new Key();
|
||||
$keys = [];
|
||||
|
||||
foreach ($value as $index => $attribute) {
|
||||
if (!\is_array($attribute)) {
|
||||
$this->message = "Attribute at index $index must be an object";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if (!isset($attribute['key'])) {
|
||||
$this->message = "Attribute at index $index is missing required field 'key'";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($attribute['type'])) {
|
||||
$this->message = "Attribute at index $index is missing required field 'type'";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate key
|
||||
if (!$keyValidator->isValid($attribute['key'])) {
|
||||
$this->message = "Invalid key for attribute at index $index: " . $keyValidator->getDescription();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for duplicate keys
|
||||
if (in_array($attribute['key'], $keys)) {
|
||||
$this->message = "Duplicate attribute key: " . $attribute['key'];
|
||||
return false;
|
||||
}
|
||||
$keys[] = $attribute['key'];
|
||||
|
||||
// Check for reserved keys
|
||||
$reservedKeys = ['$id', '$createdAt', '$updatedAt', '$permissions', '$collection'];
|
||||
if (\in_array($attribute['key'], $reservedKeys)) {
|
||||
$this->message = "Attribute key '" . $attribute['key'] . "' is reserved and cannot be used";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate type
|
||||
if (!\in_array($attribute['type'], $this->supportedTypes)) {
|
||||
$this->message = "Invalid type for attribute '" . $attribute['key'] . "': " . $attribute['type'];
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate spatial type support
|
||||
if (\in_array($attribute['type'], Database::SPATIAL_TYPES) && !$this->supportForSpatialAttributes) {
|
||||
$this->message = "Spatial attributes are not supported by the current database";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate size for string types
|
||||
if ($attribute['type'] === Database::VAR_STRING) {
|
||||
if (!isset($attribute['size']) || !is_int($attribute['size']) || $attribute['size'] < 1 || $attribute['size'] > APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH) {
|
||||
$this->message = "Invalid or missing size for string attribute '" . $attribute['key'] . "'. Size must be between 1 and " . APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate format if provided
|
||||
if (isset($attribute['format']) && $attribute['format'] !== '') {
|
||||
// Format is only allowed for string type
|
||||
if ($attribute['type'] !== Database::VAR_STRING) {
|
||||
$this->message = "Format is only allowed for string type for attribute '" . $attribute['key'] . "'";
|
||||
return false;
|
||||
}
|
||||
if (!in_array($attribute['format'], $this->supportedFormats)) {
|
||||
$this->message = "Invalid format for attribute '" . $attribute['key'] . "': " . $attribute['format'];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate required field if provided
|
||||
if (isset($attribute['required']) && !is_bool($attribute['required'])) {
|
||||
$this->message = "Invalid 'required' value for attribute '" . $attribute['key'] . "': must be a boolean";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate array field if provided
|
||||
if (isset($attribute['array']) && !is_bool($attribute['array'])) {
|
||||
$this->message = "Invalid 'array' value for attribute '" . $attribute['key'] . "': must be a boolean";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate signed field if provided
|
||||
if (isset($attribute['signed']) && !is_bool($attribute['signed'])) {
|
||||
$this->message = "Invalid 'signed' value for attribute '" . $attribute['key'] . "': must be a boolean";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate signed only for integer/float types
|
||||
if (isset($attribute['signed']) && !in_array($attribute['type'], [Database::VAR_INTEGER, Database::VAR_FLOAT])) {
|
||||
$this->message = "Attribute '" . $attribute['key'] . "': 'signed' can only be used with integer or float types";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate required and default conflict
|
||||
if (isset($attribute['required']) && $attribute['required'] === true && isset($attribute['default']) && $attribute['default'] !== null) {
|
||||
$this->message = "Attribute '" . $attribute['key'] . "' cannot have a default value when required is true";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate array and default conflict
|
||||
if (isset($attribute['array']) && $attribute['array'] === true && isset($attribute['default']) && $attribute['default'] !== null) {
|
||||
$this->message = "Attribute '" . $attribute['key'] . "' cannot have a default value when array is true";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate min/max range for integer/float
|
||||
if (isset($attribute['min']) || isset($attribute['max'])) {
|
||||
if (!in_array($attribute['type'], [Database::VAR_INTEGER, Database::VAR_FLOAT])) {
|
||||
$this->message = "Attribute '" . $attribute['key'] . "': min/max can only be used with integer or float types";
|
||||
return false;
|
||||
}
|
||||
|
||||
// If both are set, validate ordering
|
||||
if (isset($attribute['min']) && isset($attribute['max']) && $attribute['min'] > $attribute['max']) {
|
||||
$this->message = "Attribute '" . $attribute['key'] . "': minimum value must be less than or equal to maximum value";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate default value matches attribute type
|
||||
if (isset($attribute['default'])) {
|
||||
switch ($attribute['type']) {
|
||||
case Database::VAR_STRING:
|
||||
if (!is_string($attribute['default'])) {
|
||||
$this->message = "Default value for string attribute '" . $attribute['key'] . "' must be a string";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate string size
|
||||
$size = $attribute['size'] ?? 0;
|
||||
if ($size > 0) {
|
||||
$textValidator = new Text($size, 0);
|
||||
if (!$textValidator->isValid($attribute['default'])) {
|
||||
$this->message = "Default value for attribute '" . $attribute['key'] . "' exceeds maximum size of $size characters";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate format-specific defaults
|
||||
$format = $attribute['format'] ?? '';
|
||||
if ($format === APP_DATABASE_ATTRIBUTE_EMAIL) {
|
||||
$emailValidator = new Email();
|
||||
if (!$emailValidator->isValid($attribute['default'])) {
|
||||
$this->message = "Default value for email attribute '" . $attribute['key'] . "' must be a valid email address";
|
||||
return false;
|
||||
}
|
||||
} elseif ($format === APP_DATABASE_ATTRIBUTE_IP) {
|
||||
$ipValidator = new IP();
|
||||
if (!$ipValidator->isValid($attribute['default'])) {
|
||||
$this->message = "Default value for IP attribute '" . $attribute['key'] . "' must be a valid IP address";
|
||||
return false;
|
||||
}
|
||||
} elseif ($format === APP_DATABASE_ATTRIBUTE_URL) {
|
||||
$urlValidator = new URL();
|
||||
if (!$urlValidator->isValid($attribute['default'])) {
|
||||
$this->message = "Default value for URL attribute '" . $attribute['key'] . "' must be a valid URL";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Database::VAR_INTEGER:
|
||||
if (!is_int($attribute['default'])) {
|
||||
$this->message = "Default value for integer attribute '" . $attribute['key'] . "' must be an integer";
|
||||
return false;
|
||||
}
|
||||
// Validate within range if min/max specified
|
||||
if (isset($attribute['min']) || isset($attribute['max'])) {
|
||||
$min = $attribute['min'] ?? \PHP_INT_MIN;
|
||||
$max = $attribute['max'] ?? \PHP_INT_MAX;
|
||||
$rangeValidator = new Range($min, $max, Database::VAR_INTEGER);
|
||||
if (!$rangeValidator->isValid($attribute['default'])) {
|
||||
$this->message = "Default value for integer attribute '" . $attribute['key'] . "' must be between $min and $max";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Database::VAR_FLOAT:
|
||||
if (!is_float($attribute['default']) && !is_int($attribute['default'])) {
|
||||
$this->message = "Default value for float attribute '" . $attribute['key'] . "' must be a number";
|
||||
return false;
|
||||
}
|
||||
// Validate within range if min/max specified
|
||||
if (isset($attribute['min']) || isset($attribute['max'])) {
|
||||
$min = $attribute['min'] ?? -\PHP_FLOAT_MAX;
|
||||
$max = $attribute['max'] ?? \PHP_FLOAT_MAX;
|
||||
$rangeValidator = new Range($min, $max, Database::VAR_FLOAT);
|
||||
if (!$rangeValidator->isValid((float)$attribute['default'])) {
|
||||
$this->message = "Default value for float attribute '" . $attribute['key'] . "' must be between $min and $max";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Database::VAR_BOOLEAN:
|
||||
if (!is_bool($attribute['default'])) {
|
||||
$this->message = "Default value for boolean attribute '" . $attribute['key'] . "' must be a boolean";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case Database::VAR_DATETIME:
|
||||
if (!is_string($attribute['default'])) {
|
||||
$this->message = "Default value for datetime attribute '" . $attribute['key'] . "' must be a string in ISO 8601 format";
|
||||
return false;
|
||||
}
|
||||
// Basic datetime format validation
|
||||
$datetimeValidator = new DatetimeValidator();
|
||||
if (!$datetimeValidator->isValid($attribute['default'])) {
|
||||
$this->message = "Default value for datetime attribute '" . $attribute['key'] . "' must be in valid ISO 8601 format";
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate enum elements if format is enum
|
||||
if (isset($attribute['format']) && $attribute['format'] === APP_DATABASE_ATTRIBUTE_ENUM) {
|
||||
if (!isset($attribute['elements']) || !is_array($attribute['elements']) || empty($attribute['elements'])) {
|
||||
$this->message = "Attribute '" . $attribute['key'] . "' with enum format must have 'elements' array";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate each enum element
|
||||
foreach ($attribute['elements'] as $elementIndex => $element) {
|
||||
if (!is_string($element) || empty($element)) {
|
||||
$this->message = "Enum element at index $elementIndex for attribute '" . $attribute['key'] . "' must be a non-empty string";
|
||||
return false;
|
||||
}
|
||||
if (strlen($element) > Database::LENGTH_KEY) {
|
||||
$this->message = "Enum element at index $elementIndex for attribute '" . $attribute['key'] . "' exceeds maximum length of " . Database::LENGTH_KEY . " characters";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate default exists in elements
|
||||
if (isset($attribute['default']) && $attribute['default'] !== null) {
|
||||
if (!in_array($attribute['default'], $attribute['elements'], true)) {
|
||||
$this->message = "Default value for enum attribute '" . $attribute['key'] . "' must be one of the provided elements";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is array
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isArray(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return self::TYPE_ARRAY;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user