Compare commits

...
Author SHA1 Message Date
Prem Palanisamy d5c4934163 align composer.json with main, keep migration 1.* for JSON import/export 2026-03-26 23:27:52 +00:00
Prem Palanisamy e00cd52a03 Merge remote-tracking branch 'origin/main' into import-export-json 2026-03-26 23:06:14 +00:00
Eldad A. FuxandGitHub a5fa09b4ce Merge pull request #11185 from Shivangisharma4/doc-fix-typos-contributing
doc: Fix typos in CONTRIBUTING.md
2026-02-27 20:42:57 +01:00
10e2edac90 Update CONTRIBUTING.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-24 14:03:11 +05:30
Shivangisharma4 340081a67d doc: Fix typos in CONTRIBUTING.md 2026-01-24 13:58:20 +05:30
Darshan e4558faf2b regen: specs. 2026-01-20 19:26:20 +05:30
Darshan 3db634610c add: missing doc. 2026-01-20 19:26:00 +05:30
Darshan 511ca2a860 specs. 2026-01-20 18:30:13 +05:30
Darshan 0ad004e1a1 update: comment. 2026-01-20 18:29:12 +05:30
Darshan 43cd9cc086 add: tests;
fix: tests.
2026-01-20 18:28:47 +05:30
Darshan fca1563db7 fix: endpoint. 2026-01-20 18:23:04 +05:30
Darshan 9182326033 update: wire JSON import/export. 2026-01-20 17:17:41 +05:30
Steven NguyenandGitHub f0191202a0 Merge pull request #10342 from tejas-raskar/doc-10339-fix-inconsistent-dir-structure-in-contribution-docs
docs: update the directory structure in CONTRIBUTING.md
2026-01-02 15:59:24 -08:00
Steven NguyenandGitHub 44ec8de6bf Merge pull request #10946 from appwrite/1.8.x
Sync 1.8.x into main
2025-12-18 17:06:43 -08:00
Tejas Raskar 80ad740d36 docs: update the directory structure in CONTRIBUTING.md 2025-08-20 14:34:43 +05:30
26 changed files with 7743 additions and 3611 deletions
+57 -35
View File
@@ -111,7 +111,7 @@ $ git push origin [name_of_your_new_branch]
## Setup From Source
To set up a working **development environment**, just fork the project git repository and install the backend and frontend dependencies using the proper package manager and create run the docker-compose stack.
To set up a working **development environment**, just fork the project git repository and install the backend and frontend dependencies using the proper package manager and run the docker-compose stack.
> If you just want to install Appwrite for day-to-day use and not as a contributor, you can reference the [installation guide](https://github.com/appwrite/appwrite#installation), the [getting started guide](https://appwrite.io/docs/quick-starts), or the main [README](README.md) file.
@@ -173,12 +173,12 @@ Learn more at our [Technology Stack](#technology-stack) section.
- [MVVM](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel) - Appwrite console architecture
##### Container Namespace Conventions
To keep our services easy to understand within Docker we follow a naming convention for all our containers depending on it's intended use.
To keep our services easy to understand within Docker we follow a naming convention for all our containers depending on its intended use.
`appwrite-worker-X` - Workers (`src/Appwrite/Platform/Workers/*`)
`appwrite-task-X` - Tasks (`src/Appwrite/Platform/Tasks/*`)
Other containes should be named the same as their service, for example `redis` should just be called `redis`.
Other containers should be named the same as their service, for example `redis` should just be called `redis`.
##### Security
@@ -189,7 +189,7 @@ Other containes should be named the same as their service, for example `redis` s
## Modules
As Appwrite grows, we noticed approach of having all service endpoints in `app/controllers/api/[service].php` is not maintainable. Not only it creates massive files, it also doesnt contain all product's features such as workers or tasks. While there might still be some occurances of those controller files, we avoid it in all new development, and gradually migrate existing controllers to **HTTP modules**.
As Appwrite grows, we noticed approach of having all service endpoints in `app/controllers/api/[service].php` is not maintainable. Not only it creates massive files, it also doesn't contain all product's features such as workers or tasks. While there might still be some occurrences of those controller files, we avoid it in all new development, and gradually migrate existing controllers to **HTTP modules**.
### HTTP Endpoints
@@ -204,7 +204,7 @@ Tips and tricks:
1. If endpoint doesn't have resource, use service name as resource name too
> Example: `Modules/Sites/Http/Sites/Get.php`
2. If there are multiple resources, use then all in folder structure
2. If there are multiple resources, use them all in folder structure
> Example: `Modules/Sites/Http/Deployments/Builds/Create.php`
3. Action can only be `Get`, `Create`, `Update`, `Delete` or `XList`
@@ -222,51 +222,73 @@ Appwrite's current structure is a combination of both [Monolithic](https://en.wi
```bash
.
├── app # Main application
│ ├── assets
│ │ ├── dbip
│ │ ├── fonts
│ │ └── security
│ ├── config # Config files
│ │ ├── avatars
│ │ ├── collections
│ │ ├── locale
│ │ ├── specs
│ │ ├── storage
│ │ └── templates
│ ├── controllers # API & dashboard controllers
│ │ ├── api
│ │ ├── shared
│ │ └── web
│ ├── db # DB schemas
├── sdks # SDKs generated copies (used for generating code examples)
── tasks # Server CLI commands
├── views # HTML server-side templates
└── workers # Background workers
│ ├── init # DB schemas
│ └── database
── views # HTML server-side templates
├── general
└── install
├── bin # Server executables (tasks & workers)
├── docker # Docker related resources and configs
├── dev # Debugger config
├── docs # Docs and tutorials
│ ├── examples
│ ├── lists
│ ├── references
│ ├── sdks
│ ├── services
│ ├── specs
│ └── tutorials
├── public # Public files
│ ├── dist
│ ├── fonts
│ ├── images
│ ├── scripts
── styles
├── src # Supporting libraries (each lib has one role, common libs are released as individual projects)
│ └── Appwrite
├── Auth
├── Detector
├── Docker
| ├── DSN
├── Event
├── Extend
├── GraphQL
├── Messaging
├── Migration
├── Network
├── OpenSSL
├── Promises
├── Specification
├── Task
├── Template
├── URL
── Utopia
│ ├── sdk-console
── sdk-project
│ └── sdk-web
├── src # Supporting libraries (each lib has one role, common libs are released as
│ ├── Appwrite
├── Auth
├── Certificates
├── Deletes
├── Detector
├── Docker
├── Event
├── Extend
├── Functions/Validator
├── GraphQL
├── Hooks
├── Messaging
├── Migration
├── Network
├── OpenSSL
├── Platform
── Promises
│ │ ├── PubSub
│ │ ├── SDK
│ │ ├── Task/Validator
│ │ ├── Template
│ │ ├── Transformation
│ │ ├── URL
│ │ ├── Utopia
│ │ └── Vcs
│ └── Executor
└── tests # End to end & unit tests
├── benchmarks
├── e2e
├── extensions
├── resources
└── unit
```
@@ -395,7 +417,7 @@ These are the current metrics we collect usage stats for:
> Note: The curly brackets in the metric name represents a template and is replaced with a value when the metric is processed.
Metrics are collected within 3 scopes Daily, monthly, an infinity. Adding new usage metric in order to aggregate usage stats is very simple, but very much dependent on where do you want to collect
Metrics are collected within 3 scopes Daily, monthly, and infinity. Adding new usage metric in order to aggregate usage stats is very simple, but very much dependent on where do you want to collect
statistics ,via API or via background worker. For both cases you will need to add a `const` variable in `app/init.php` under the usage metrics list using the naming convention `METRIC_<RESOURCE_NAME>` as shown below.
```php
@@ -661,7 +683,7 @@ docker compose exec redis redis-cli FLUSHALL
## Using preview domains locally
Appwrite Functions are automatically given a domain you can visit to execute the function. This domain has format `[SOMETHING].functions.localhost` unless you changed `_APP_DOMAIN_FUNCTIONS` environment variable. This default value works great when running Appwrite locally, but it can be impossible to use preview domains with Cloud woekspaces such as Gitpod or GitHub Codespaces.
Appwrite Functions are automatically given a domain you can visit to execute the function. This domain has format `[SOMETHING].functions.localhost` unless you changed `_APP_DOMAIN_FUNCTIONS` environment variable. This default value works great when running Appwrite locally, but it can be impossible to use preview domains with Cloud workspaces such as Gitpod or GitHub Codespaces.
To use preview domains on Cloud workspaces, you can visit hostname provided by them, and supply function's preview domain as URL parameter:
+15 -15
View File
@@ -57,21 +57,21 @@
"emails.recovery.thanks": "Thanks,",
"emails.recovery.buttonText": "Reset password",
"emails.recovery.signature": "{{project}} team",
"emails.csvExport.success.subject": "Your CSV export is ready",
"emails.csvExport.success.preview": "Your data export has been completed successfully.",
"emails.csvExport.success.hello": "Hello {{user}},",
"emails.csvExport.success.body": "Your CSV export is ready to download. Click the button below to download your data export.",
"emails.csvExport.success.footer": "This download link will expire in 1 hour.",
"emails.csvExport.success.thanks": "Thanks,",
"emails.csvExport.success.buttonText": "Download CSV",
"emails.csvExport.success.signature": "Appwrite team",
"emails.csvExport.failure.subject": "Your CSV export failed - file too large",
"emails.csvExport.failure.preview": "Your data export failed because the file size exceeds your plan limit.",
"emails.csvExport.failure.hello": "Hello {{user}},",
"emails.csvExport.failure.body": "Your CSV export could not be completed because the export file size ({{size}}MB) exceeds your plan limit. Please consider upgrading your plan or exporting a smaller dataset.",
"emails.csvExport.failure.footer": "If you have any questions, please contact our support team.",
"emails.csvExport.failure.thanks": "Thanks,",
"emails.csvExport.failure.signature": "{{project}} team",
"emails.dataExport.success.subject": "Your {{type}} export is ready",
"emails.dataExport.success.preview": "Your data export has been completed successfully.",
"emails.dataExport.success.hello": "Hello {{user}},",
"emails.dataExport.success.body": "Your {{type}} export is ready to download. Click the button below to download your data export.",
"emails.dataExport.success.footer": "This download link will expire in 1 hour.",
"emails.dataExport.success.thanks": "Thanks,",
"emails.dataExport.success.buttonText": "Download {{type}}",
"emails.dataExport.success.signature": "{{platform}} team",
"emails.dataExport.failure.subject": "Your {{type}} export failed - file too large",
"emails.dataExport.failure.preview": "Your data export failed because the file size exceeds your plan limit.",
"emails.dataExport.failure.hello": "Hello {{user}},",
"emails.dataExport.failure.body": "Your {{type}} export could not be completed because the export file size ({{size}}MB) exceeds your plan limit. Please consider upgrading your plan or exporting a smaller dataset.",
"emails.dataExport.failure.footer": "If you have any questions, please contact our support team.",
"emails.dataExport.failure.thanks": "Thanks,",
"emails.dataExport.failure.signature": "{{project}} team",
"emails.invitation.subject": "Invitation to {{team}} Team at {{project}}",
"emails.invitation.preview": "{{owner}} invited you to join {{team}} at {{project}}",
"emails.invitation.hello": "Hello {{user}},",
+90 -76
View File
@@ -555,7 +555,7 @@
"x-appwrite": {
"method": "updateMFA",
"group": "mfa",
"weight": 277,
"weight": 255,
"cookies": false,
"type": "",
"demo": "account\/update-mfa.md",
@@ -627,7 +627,7 @@
"x-appwrite": {
"method": "createMfaAuthenticator",
"group": "mfa",
"weight": 279,
"weight": 257,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-authenticator.md",
@@ -751,7 +751,7 @@
"x-appwrite": {
"method": "updateMfaAuthenticator",
"group": "mfa",
"weight": 280,
"weight": 258,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-authenticator.md",
@@ -891,7 +891,7 @@
"x-appwrite": {
"method": "deleteMfaAuthenticator",
"group": "mfa",
"weight": 281,
"weight": 259,
"cookies": false,
"type": "",
"demo": "account\/delete-mfa-authenticator.md",
@@ -1015,7 +1015,7 @@
"x-appwrite": {
"method": "createMfaChallenge",
"group": "mfa",
"weight": 285,
"weight": 263,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-challenge.md",
@@ -1149,7 +1149,7 @@
"x-appwrite": {
"method": "updateMfaChallenge",
"group": "mfa",
"weight": 286,
"weight": 264,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-challenge.md",
@@ -1287,7 +1287,7 @@
"x-appwrite": {
"method": "listMfaFactors",
"group": "mfa",
"weight": 278,
"weight": 256,
"cookies": false,
"type": "",
"demo": "account\/list-mfa-factors.md",
@@ -1388,7 +1388,7 @@
"x-appwrite": {
"method": "getMfaRecoveryCodes",
"group": "mfa",
"weight": 284,
"weight": 262,
"cookies": false,
"type": "",
"demo": "account\/get-mfa-recovery-codes.md",
@@ -1487,7 +1487,7 @@
"x-appwrite": {
"method": "createMfaRecoveryCodes",
"group": "mfa",
"weight": 282,
"weight": 260,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-recovery-codes.md",
@@ -1586,7 +1586,7 @@
"x-appwrite": {
"method": "updateMfaRecoveryCodes",
"group": "mfa",
"weight": 283,
"weight": 261,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-recovery-codes.md",
@@ -4051,7 +4051,7 @@
"x-appwrite": {
"method": "getBrowser",
"group": null,
"weight": 288,
"weight": 266,
"cookies": false,
"type": "location",
"demo": "avatars\/get-browser.md",
@@ -4179,7 +4179,7 @@
"x-appwrite": {
"method": "getCreditCard",
"group": null,
"weight": 287,
"weight": 265,
"cookies": false,
"type": "location",
"demo": "avatars\/get-credit-card.md",
@@ -4313,7 +4313,7 @@
"x-appwrite": {
"method": "getFavicon",
"group": null,
"weight": 291,
"weight": 269,
"cookies": false,
"type": "location",
"demo": "avatars\/get-favicon.md",
@@ -4373,7 +4373,7 @@
"x-appwrite": {
"method": "getFlag",
"group": null,
"weight": 289,
"weight": 267,
"cookies": false,
"type": "location",
"demo": "avatars\/get-flag.md",
@@ -4863,7 +4863,7 @@
"x-appwrite": {
"method": "getImage",
"group": null,
"weight": 290,
"weight": 268,
"cookies": false,
"type": "location",
"demo": "avatars\/get-image.md",
@@ -4947,7 +4947,7 @@
"x-appwrite": {
"method": "getInitials",
"group": null,
"weight": 293,
"weight": 271,
"cookies": false,
"type": "location",
"demo": "avatars\/get-initials.md",
@@ -5041,7 +5041,7 @@
"x-appwrite": {
"method": "getQR",
"group": null,
"weight": 292,
"weight": 270,
"cookies": false,
"type": "location",
"demo": "avatars\/get-qr.md",
@@ -5135,7 +5135,7 @@
"x-appwrite": {
"method": "getScreenshot",
"group": null,
"weight": 294,
"weight": 272,
"cookies": false,
"type": "location",
"demo": "avatars\/get-screenshot.md",
@@ -5888,7 +5888,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 362,
"weight": 340,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@@ -5955,7 +5955,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 358,
"weight": 336,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@@ -6026,7 +6026,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 359,
"weight": 337,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@@ -6090,7 +6090,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 360,
"weight": 338,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@@ -6168,7 +6168,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 361,
"weight": 339,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@@ -6234,7 +6234,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 363,
"weight": 341,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@@ -6319,7 +6319,7 @@
"x-appwrite": {
"method": "listDocuments",
"group": "documents",
"weight": 321,
"weight": 299,
"cookies": false,
"type": "",
"demo": "databases\/list-documents.md",
@@ -6431,7 +6431,7 @@
"x-appwrite": {
"method": "createDocument",
"group": "documents",
"weight": 313,
"weight": 291,
"cookies": false,
"type": "",
"demo": "databases\/create-document.md",
@@ -6592,7 +6592,7 @@
"x-appwrite": {
"method": "getDocument",
"group": "documents",
"weight": 314,
"weight": 292,
"cookies": false,
"type": "",
"demo": "databases\/get-document.md",
@@ -6703,7 +6703,7 @@
"x-appwrite": {
"method": "upsertDocument",
"group": "documents",
"weight": 317,
"weight": 295,
"cookies": false,
"type": "",
"demo": "databases\/upsert-document.md",
@@ -6858,7 +6858,7 @@
"x-appwrite": {
"method": "updateDocument",
"group": "documents",
"weight": 315,
"weight": 293,
"cookies": false,
"type": "",
"demo": "databases\/update-document.md",
@@ -6970,7 +6970,7 @@
"x-appwrite": {
"method": "deleteDocument",
"group": "documents",
"weight": 319,
"weight": 297,
"cookies": false,
"type": "",
"demo": "databases\/delete-document.md",
@@ -7077,7 +7077,7 @@
"x-appwrite": {
"method": "decrementDocumentAttribute",
"group": "documents",
"weight": 324,
"weight": 302,
"cookies": false,
"type": "",
"demo": "databases\/decrement-document-attribute.md",
@@ -7206,7 +7206,7 @@
"x-appwrite": {
"method": "incrementDocumentAttribute",
"group": "documents",
"weight": 323,
"weight": 301,
"cookies": false,
"type": "",
"demo": "databases\/increment-document-attribute.md",
@@ -7335,7 +7335,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 455,
"weight": 433,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@@ -7422,7 +7422,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 453,
"weight": 431,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@@ -7540,7 +7540,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 454,
"weight": 432,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@@ -7615,7 +7615,7 @@
"x-appwrite": {
"method": "query",
"group": "graphql",
"weight": 214,
"weight": 190,
"cookies": false,
"type": "graphql",
"demo": "graphql\/query.md",
@@ -7669,7 +7669,7 @@
"x-appwrite": {
"method": "mutation",
"group": "graphql",
"weight": 213,
"weight": 189,
"cookies": false,
"type": "graphql",
"demo": "graphql\/mutation.md",
@@ -8155,7 +8155,7 @@
"x-appwrite": {
"method": "createSubscriber",
"group": "subscribers",
"weight": 261,
"weight": 239,
"cookies": false,
"type": "",
"demo": "messaging\/create-subscriber.md",
@@ -8239,7 +8239,7 @@
"x-appwrite": {
"method": "deleteSubscriber",
"group": "subscribers",
"weight": 265,
"weight": 243,
"cookies": false,
"type": "",
"demo": "messaging\/delete-subscriber.md",
@@ -8315,7 +8315,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 526,
"weight": 529,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@@ -8414,7 +8414,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 524,
"weight": 527,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@@ -8516,7 +8516,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 525,
"weight": 528,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@@ -8590,7 +8590,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 527,
"weight": 530,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@@ -8682,7 +8682,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 528,
"weight": 531,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@@ -8751,7 +8751,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 530,
"weight": 533,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@@ -8831,7 +8831,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 529,
"weight": 532,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@@ -9061,7 +9061,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 531,
"weight": 534,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@@ -9148,7 +9148,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 427,
"weight": 405,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@@ -9218,7 +9218,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 423,
"weight": 401,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@@ -9292,7 +9292,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 424,
"weight": 402,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@@ -9359,7 +9359,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 425,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@@ -9440,7 +9440,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 426,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@@ -9509,7 +9509,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 428,
"weight": 406,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@@ -9597,7 +9597,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 419,
"weight": 397,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@@ -9708,7 +9708,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 411,
"weight": 389,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@@ -9864,7 +9864,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 412,
"weight": 390,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@@ -9974,7 +9974,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 415,
"weight": 393,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@@ -10124,7 +10124,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 413,
"weight": 391,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@@ -10235,7 +10235,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 417,
"weight": 395,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@@ -10341,7 +10341,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 422,
"weight": 400,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@@ -10469,7 +10469,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 421,
"weight": 399,
"cookies": false,
"type": "",
"demo": "tablesdb\/increment-row-column.md",
@@ -10597,7 +10597,7 @@
"x-appwrite": {
"method": "list",
"group": "teams",
"weight": 134,
"weight": 110,
"cookies": false,
"type": "",
"demo": "teams\/list.md",
@@ -10686,7 +10686,7 @@
"x-appwrite": {
"method": "create",
"group": "teams",
"weight": 133,
"weight": 109,
"cookies": false,
"type": "",
"demo": "teams\/create.md",
@@ -10773,7 +10773,7 @@
"x-appwrite": {
"method": "get",
"group": "teams",
"weight": 135,
"weight": 111,
"cookies": false,
"type": "",
"demo": "teams\/get.md",
@@ -10837,7 +10837,7 @@
"x-appwrite": {
"method": "updateName",
"group": "teams",
"weight": 137,
"weight": 113,
"cookies": false,
"type": "",
"demo": "teams\/update-name.md",
@@ -10913,7 +10913,7 @@
"x-appwrite": {
"method": "delete",
"group": "teams",
"weight": 139,
"weight": 115,
"cookies": false,
"type": "",
"demo": "teams\/delete.md",
@@ -10979,7 +10979,7 @@
"x-appwrite": {
"method": "listMemberships",
"group": "memberships",
"weight": 141,
"weight": 117,
"cookies": false,
"type": "",
"demo": "teams\/list-memberships.md",
@@ -11078,7 +11078,7 @@
"x-appwrite": {
"method": "createMembership",
"group": "memberships",
"weight": 140,
"weight": 116,
"cookies": false,
"type": "",
"demo": "teams\/create-membership.md",
@@ -11201,7 +11201,7 @@
"x-appwrite": {
"method": "getMembership",
"group": "memberships",
"weight": 142,
"weight": 118,
"cookies": false,
"type": "",
"demo": "teams\/get-membership.md",
@@ -11275,7 +11275,7 @@
"x-appwrite": {
"method": "updateMembership",
"group": "memberships",
"weight": 143,
"weight": 119,
"cookies": false,
"type": "",
"demo": "teams\/update-membership.md",
@@ -11371,7 +11371,7 @@
"x-appwrite": {
"method": "deleteMembership",
"group": "memberships",
"weight": 145,
"weight": 121,
"cookies": false,
"type": "",
"demo": "teams\/delete-membership.md",
@@ -11447,7 +11447,7 @@
"x-appwrite": {
"method": "updateMembershipStatus",
"group": "memberships",
"weight": 144,
"weight": 120,
"cookies": false,
"type": "",
"demo": "teams\/update-membership-status.md",
@@ -11547,7 +11547,7 @@
"x-appwrite": {
"method": "getPrefs",
"group": "teams",
"weight": 136,
"weight": 112,
"cookies": false,
"type": "",
"demo": "teams\/get-prefs.md",
@@ -11610,7 +11610,7 @@
"x-appwrite": {
"method": "updatePrefs",
"group": "teams",
"weight": 138,
"weight": 114,
"cookies": false,
"type": "",
"demo": "teams\/update-prefs.md",
@@ -13454,6 +13454,16 @@
"description": "Total number of chunks uploaded",
"x-example": 17890,
"format": "int32"
},
"encryption": {
"type": "boolean",
"description": "Whether file contents are encrypted at rest.",
"x-example": true
},
"compression": {
"type": "string",
"description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).",
"x-example": "gzip"
}
},
"required": [
@@ -13467,7 +13477,9 @@
"mimeType",
"sizeOriginal",
"chunksTotal",
"chunksUploaded"
"chunksUploaded",
"encryption",
"compression"
],
"example": {
"$id": "5e5ea5c16897e",
@@ -13482,7 +13494,9 @@
"mimeType": "image\/png",
"sizeOriginal": 17890,
"chunksTotal": 17890,
"chunksUploaded": 17890
"chunksUploaded": 17890,
"encryption": true,
"compression": "gzip"
}
},
"team": {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+74 -74
View File
@@ -555,7 +555,7 @@
"x-appwrite": {
"method": "updateMFA",
"group": "mfa",
"weight": 277,
"weight": 255,
"cookies": false,
"type": "",
"demo": "account\/update-mfa.md",
@@ -627,7 +627,7 @@
"x-appwrite": {
"method": "createMfaAuthenticator",
"group": "mfa",
"weight": 279,
"weight": 257,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-authenticator.md",
@@ -751,7 +751,7 @@
"x-appwrite": {
"method": "updateMfaAuthenticator",
"group": "mfa",
"weight": 280,
"weight": 258,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-authenticator.md",
@@ -891,7 +891,7 @@
"x-appwrite": {
"method": "deleteMfaAuthenticator",
"group": "mfa",
"weight": 281,
"weight": 259,
"cookies": false,
"type": "",
"demo": "account\/delete-mfa-authenticator.md",
@@ -1015,7 +1015,7 @@
"x-appwrite": {
"method": "createMfaChallenge",
"group": "mfa",
"weight": 285,
"weight": 263,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-challenge.md",
@@ -1149,7 +1149,7 @@
"x-appwrite": {
"method": "updateMfaChallenge",
"group": "mfa",
"weight": 286,
"weight": 264,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-challenge.md",
@@ -1287,7 +1287,7 @@
"x-appwrite": {
"method": "listMfaFactors",
"group": "mfa",
"weight": 278,
"weight": 256,
"cookies": false,
"type": "",
"demo": "account\/list-mfa-factors.md",
@@ -1388,7 +1388,7 @@
"x-appwrite": {
"method": "getMfaRecoveryCodes",
"group": "mfa",
"weight": 284,
"weight": 262,
"cookies": false,
"type": "",
"demo": "account\/get-mfa-recovery-codes.md",
@@ -1487,7 +1487,7 @@
"x-appwrite": {
"method": "createMfaRecoveryCodes",
"group": "mfa",
"weight": 282,
"weight": 260,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-recovery-codes.md",
@@ -1586,7 +1586,7 @@
"x-appwrite": {
"method": "updateMfaRecoveryCodes",
"group": "mfa",
"weight": 283,
"weight": 261,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-recovery-codes.md",
@@ -4051,7 +4051,7 @@
"x-appwrite": {
"method": "getBrowser",
"group": null,
"weight": 288,
"weight": 266,
"cookies": false,
"type": "location",
"demo": "avatars\/get-browser.md",
@@ -4179,7 +4179,7 @@
"x-appwrite": {
"method": "getCreditCard",
"group": null,
"weight": 287,
"weight": 265,
"cookies": false,
"type": "location",
"demo": "avatars\/get-credit-card.md",
@@ -4313,7 +4313,7 @@
"x-appwrite": {
"method": "getFavicon",
"group": null,
"weight": 291,
"weight": 269,
"cookies": false,
"type": "location",
"demo": "avatars\/get-favicon.md",
@@ -4373,7 +4373,7 @@
"x-appwrite": {
"method": "getFlag",
"group": null,
"weight": 289,
"weight": 267,
"cookies": false,
"type": "location",
"demo": "avatars\/get-flag.md",
@@ -4863,7 +4863,7 @@
"x-appwrite": {
"method": "getImage",
"group": null,
"weight": 290,
"weight": 268,
"cookies": false,
"type": "location",
"demo": "avatars\/get-image.md",
@@ -4947,7 +4947,7 @@
"x-appwrite": {
"method": "getInitials",
"group": null,
"weight": 293,
"weight": 271,
"cookies": false,
"type": "location",
"demo": "avatars\/get-initials.md",
@@ -5041,7 +5041,7 @@
"x-appwrite": {
"method": "getQR",
"group": null,
"weight": 292,
"weight": 270,
"cookies": false,
"type": "location",
"demo": "avatars\/get-qr.md",
@@ -5135,7 +5135,7 @@
"x-appwrite": {
"method": "getScreenshot",
"group": null,
"weight": 294,
"weight": 272,
"cookies": false,
"type": "location",
"demo": "avatars\/get-screenshot.md",
@@ -5888,7 +5888,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 362,
"weight": 340,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@@ -5955,7 +5955,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 358,
"weight": 336,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@@ -6026,7 +6026,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 359,
"weight": 337,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@@ -6090,7 +6090,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 360,
"weight": 338,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@@ -6168,7 +6168,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 361,
"weight": 339,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@@ -6234,7 +6234,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 363,
"weight": 341,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@@ -6319,7 +6319,7 @@
"x-appwrite": {
"method": "listDocuments",
"group": "documents",
"weight": 321,
"weight": 299,
"cookies": false,
"type": "",
"demo": "databases\/list-documents.md",
@@ -6431,7 +6431,7 @@
"x-appwrite": {
"method": "createDocument",
"group": "documents",
"weight": 313,
"weight": 291,
"cookies": false,
"type": "",
"demo": "databases\/create-document.md",
@@ -6592,7 +6592,7 @@
"x-appwrite": {
"method": "getDocument",
"group": "documents",
"weight": 314,
"weight": 292,
"cookies": false,
"type": "",
"demo": "databases\/get-document.md",
@@ -6703,7 +6703,7 @@
"x-appwrite": {
"method": "upsertDocument",
"group": "documents",
"weight": 317,
"weight": 295,
"cookies": false,
"type": "",
"demo": "databases\/upsert-document.md",
@@ -6858,7 +6858,7 @@
"x-appwrite": {
"method": "updateDocument",
"group": "documents",
"weight": 315,
"weight": 293,
"cookies": false,
"type": "",
"demo": "databases\/update-document.md",
@@ -6970,7 +6970,7 @@
"x-appwrite": {
"method": "deleteDocument",
"group": "documents",
"weight": 319,
"weight": 297,
"cookies": false,
"type": "",
"demo": "databases\/delete-document.md",
@@ -7077,7 +7077,7 @@
"x-appwrite": {
"method": "decrementDocumentAttribute",
"group": "documents",
"weight": 324,
"weight": 302,
"cookies": false,
"type": "",
"demo": "databases\/decrement-document-attribute.md",
@@ -7206,7 +7206,7 @@
"x-appwrite": {
"method": "incrementDocumentAttribute",
"group": "documents",
"weight": 323,
"weight": 301,
"cookies": false,
"type": "",
"demo": "databases\/increment-document-attribute.md",
@@ -7335,7 +7335,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 455,
"weight": 433,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@@ -7422,7 +7422,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 453,
"weight": 431,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@@ -7540,7 +7540,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 454,
"weight": 432,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@@ -7615,7 +7615,7 @@
"x-appwrite": {
"method": "query",
"group": "graphql",
"weight": 214,
"weight": 190,
"cookies": false,
"type": "graphql",
"demo": "graphql\/query.md",
@@ -7669,7 +7669,7 @@
"x-appwrite": {
"method": "mutation",
"group": "graphql",
"weight": 213,
"weight": 189,
"cookies": false,
"type": "graphql",
"demo": "graphql\/mutation.md",
@@ -8155,7 +8155,7 @@
"x-appwrite": {
"method": "createSubscriber",
"group": "subscribers",
"weight": 261,
"weight": 239,
"cookies": false,
"type": "",
"demo": "messaging\/create-subscriber.md",
@@ -8239,7 +8239,7 @@
"x-appwrite": {
"method": "deleteSubscriber",
"group": "subscribers",
"weight": 265,
"weight": 243,
"cookies": false,
"type": "",
"demo": "messaging\/delete-subscriber.md",
@@ -8315,7 +8315,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 526,
"weight": 529,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@@ -8414,7 +8414,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 524,
"weight": 527,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@@ -8516,7 +8516,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 525,
"weight": 528,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@@ -8590,7 +8590,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 527,
"weight": 530,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@@ -8682,7 +8682,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 528,
"weight": 531,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@@ -8751,7 +8751,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 530,
"weight": 533,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@@ -8831,7 +8831,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 529,
"weight": 532,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@@ -9061,7 +9061,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 531,
"weight": 534,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@@ -9148,7 +9148,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 427,
"weight": 405,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@@ -9218,7 +9218,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 423,
"weight": 401,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@@ -9292,7 +9292,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 424,
"weight": 402,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@@ -9359,7 +9359,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 425,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@@ -9440,7 +9440,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 426,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@@ -9509,7 +9509,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 428,
"weight": 406,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@@ -9597,7 +9597,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 419,
"weight": 397,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@@ -9708,7 +9708,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 411,
"weight": 389,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@@ -9864,7 +9864,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 412,
"weight": 390,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@@ -9974,7 +9974,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 415,
"weight": 393,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@@ -10124,7 +10124,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 413,
"weight": 391,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@@ -10235,7 +10235,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 417,
"weight": 395,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@@ -10341,7 +10341,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 422,
"weight": 400,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@@ -10469,7 +10469,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 421,
"weight": 399,
"cookies": false,
"type": "",
"demo": "tablesdb\/increment-row-column.md",
@@ -10597,7 +10597,7 @@
"x-appwrite": {
"method": "list",
"group": "teams",
"weight": 134,
"weight": 110,
"cookies": false,
"type": "",
"demo": "teams\/list.md",
@@ -10686,7 +10686,7 @@
"x-appwrite": {
"method": "create",
"group": "teams",
"weight": 133,
"weight": 109,
"cookies": false,
"type": "",
"demo": "teams\/create.md",
@@ -10773,7 +10773,7 @@
"x-appwrite": {
"method": "get",
"group": "teams",
"weight": 135,
"weight": 111,
"cookies": false,
"type": "",
"demo": "teams\/get.md",
@@ -10837,7 +10837,7 @@
"x-appwrite": {
"method": "updateName",
"group": "teams",
"weight": 137,
"weight": 113,
"cookies": false,
"type": "",
"demo": "teams\/update-name.md",
@@ -10913,7 +10913,7 @@
"x-appwrite": {
"method": "delete",
"group": "teams",
"weight": 139,
"weight": 115,
"cookies": false,
"type": "",
"demo": "teams\/delete.md",
@@ -10979,7 +10979,7 @@
"x-appwrite": {
"method": "listMemberships",
"group": "memberships",
"weight": 141,
"weight": 117,
"cookies": false,
"type": "",
"demo": "teams\/list-memberships.md",
@@ -11078,7 +11078,7 @@
"x-appwrite": {
"method": "createMembership",
"group": "memberships",
"weight": 140,
"weight": 116,
"cookies": false,
"type": "",
"demo": "teams\/create-membership.md",
@@ -11201,7 +11201,7 @@
"x-appwrite": {
"method": "getMembership",
"group": "memberships",
"weight": 142,
"weight": 118,
"cookies": false,
"type": "",
"demo": "teams\/get-membership.md",
@@ -11275,7 +11275,7 @@
"x-appwrite": {
"method": "updateMembership",
"group": "memberships",
"weight": 143,
"weight": 119,
"cookies": false,
"type": "",
"demo": "teams\/update-membership.md",
@@ -11371,7 +11371,7 @@
"x-appwrite": {
"method": "deleteMembership",
"group": "memberships",
"weight": 145,
"weight": 121,
"cookies": false,
"type": "",
"demo": "teams\/delete-membership.md",
@@ -11447,7 +11447,7 @@
"x-appwrite": {
"method": "updateMembershipStatus",
"group": "memberships",
"weight": 144,
"weight": 120,
"cookies": false,
"type": "",
"demo": "teams\/update-membership-status.md",
@@ -11547,7 +11547,7 @@
"x-appwrite": {
"method": "getPrefs",
"group": "teams",
"weight": 136,
"weight": 112,
"cookies": false,
"type": "",
"demo": "teams\/get-prefs.md",
@@ -11610,7 +11610,7 @@
"x-appwrite": {
"method": "updatePrefs",
"group": "teams",
"weight": 138,
"weight": 114,
"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
+90 -76
View File
@@ -612,7 +612,7 @@
"x-appwrite": {
"method": "updateMFA",
"group": "mfa",
"weight": 277,
"weight": 255,
"cookies": false,
"type": "",
"demo": "account\/update-mfa.md",
@@ -687,7 +687,7 @@
"x-appwrite": {
"method": "createMfaAuthenticator",
"group": "mfa",
"weight": 279,
"weight": 257,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-authenticator.md",
@@ -811,7 +811,7 @@
"x-appwrite": {
"method": "updateMfaAuthenticator",
"group": "mfa",
"weight": 280,
"weight": 258,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-authenticator.md",
@@ -952,7 +952,7 @@
"x-appwrite": {
"method": "deleteMfaAuthenticator",
"group": "mfa",
"weight": 281,
"weight": 259,
"cookies": false,
"type": "",
"demo": "account\/delete-mfa-authenticator.md",
@@ -1076,7 +1076,7 @@
"x-appwrite": {
"method": "createMfaChallenge",
"group": "mfa",
"weight": 285,
"weight": 263,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-challenge.md",
@@ -1213,7 +1213,7 @@
"x-appwrite": {
"method": "updateMfaChallenge",
"group": "mfa",
"weight": 286,
"weight": 264,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-challenge.md",
@@ -1353,7 +1353,7 @@
"x-appwrite": {
"method": "listMfaFactors",
"group": "mfa",
"weight": 278,
"weight": 256,
"cookies": false,
"type": "",
"demo": "account\/list-mfa-factors.md",
@@ -1454,7 +1454,7 @@
"x-appwrite": {
"method": "getMfaRecoveryCodes",
"group": "mfa",
"weight": 284,
"weight": 262,
"cookies": false,
"type": "",
"demo": "account\/get-mfa-recovery-codes.md",
@@ -1555,7 +1555,7 @@
"x-appwrite": {
"method": "createMfaRecoveryCodes",
"group": "mfa",
"weight": 282,
"weight": 260,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-recovery-codes.md",
@@ -1656,7 +1656,7 @@
"x-appwrite": {
"method": "updateMfaRecoveryCodes",
"group": "mfa",
"weight": 283,
"weight": 261,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-recovery-codes.md",
@@ -4203,7 +4203,7 @@
"x-appwrite": {
"method": "getBrowser",
"group": null,
"weight": 288,
"weight": 266,
"cookies": false,
"type": "location",
"demo": "avatars\/get-browser.md",
@@ -4329,7 +4329,7 @@
"x-appwrite": {
"method": "getCreditCard",
"group": null,
"weight": 287,
"weight": 265,
"cookies": false,
"type": "location",
"demo": "avatars\/get-credit-card.md",
@@ -4461,7 +4461,7 @@
"x-appwrite": {
"method": "getFavicon",
"group": null,
"weight": 291,
"weight": 269,
"cookies": false,
"type": "location",
"demo": "avatars\/get-favicon.md",
@@ -4525,7 +4525,7 @@
"x-appwrite": {
"method": "getFlag",
"group": null,
"weight": 289,
"weight": 267,
"cookies": false,
"type": "location",
"demo": "avatars\/get-flag.md",
@@ -5013,7 +5013,7 @@
"x-appwrite": {
"method": "getImage",
"group": null,
"weight": 290,
"weight": 268,
"cookies": false,
"type": "location",
"demo": "avatars\/get-image.md",
@@ -5097,7 +5097,7 @@
"x-appwrite": {
"method": "getInitials",
"group": null,
"weight": 293,
"weight": 271,
"cookies": false,
"type": "location",
"demo": "avatars\/get-initials.md",
@@ -5189,7 +5189,7 @@
"x-appwrite": {
"method": "getQR",
"group": null,
"weight": 292,
"weight": 270,
"cookies": false,
"type": "location",
"demo": "avatars\/get-qr.md",
@@ -5281,7 +5281,7 @@
"x-appwrite": {
"method": "getScreenshot",
"group": null,
"weight": 294,
"weight": 272,
"cookies": false,
"type": "location",
"demo": "avatars\/get-screenshot.md",
@@ -5994,7 +5994,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 362,
"weight": 340,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@@ -6061,7 +6061,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 358,
"weight": 336,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@@ -6132,7 +6132,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 359,
"weight": 337,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@@ -6195,7 +6195,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 360,
"weight": 338,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@@ -6274,7 +6274,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 361,
"weight": 339,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@@ -6339,7 +6339,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 363,
"weight": 341,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@@ -6420,7 +6420,7 @@
"x-appwrite": {
"method": "listDocuments",
"group": "documents",
"weight": 321,
"weight": 299,
"cookies": false,
"type": "",
"demo": "databases\/list-documents.md",
@@ -6524,7 +6524,7 @@
"x-appwrite": {
"method": "createDocument",
"group": "documents",
"weight": 313,
"weight": 291,
"cookies": false,
"type": "",
"demo": "databases\/create-document.md",
@@ -6683,7 +6683,7 @@
"x-appwrite": {
"method": "getDocument",
"group": "documents",
"weight": 314,
"weight": 292,
"cookies": false,
"type": "",
"demo": "databases\/get-document.md",
@@ -6786,7 +6786,7 @@
"x-appwrite": {
"method": "upsertDocument",
"group": "documents",
"weight": 317,
"weight": 295,
"cookies": false,
"type": "",
"demo": "databases\/upsert-document.md",
@@ -6937,7 +6937,7 @@
"x-appwrite": {
"method": "updateDocument",
"group": "documents",
"weight": 315,
"weight": 293,
"cookies": false,
"type": "",
"demo": "databases\/update-document.md",
@@ -7047,7 +7047,7 @@
"x-appwrite": {
"method": "deleteDocument",
"group": "documents",
"weight": 319,
"weight": 297,
"cookies": false,
"type": "",
"demo": "databases\/delete-document.md",
@@ -7148,7 +7148,7 @@
"x-appwrite": {
"method": "decrementDocumentAttribute",
"group": "documents",
"weight": 324,
"weight": 302,
"cookies": false,
"type": "",
"demo": "databases\/decrement-document-attribute.md",
@@ -7271,7 +7271,7 @@
"x-appwrite": {
"method": "incrementDocumentAttribute",
"group": "documents",
"weight": 323,
"weight": 301,
"cookies": false,
"type": "",
"demo": "databases\/increment-document-attribute.md",
@@ -7392,7 +7392,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 455,
"weight": 433,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@@ -7475,7 +7475,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 453,
"weight": 431,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@@ -7594,7 +7594,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 454,
"weight": 432,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@@ -7666,7 +7666,7 @@
"x-appwrite": {
"method": "query",
"group": "graphql",
"weight": 214,
"weight": 190,
"cookies": false,
"type": "graphql",
"demo": "graphql\/query.md",
@@ -7741,7 +7741,7 @@
"x-appwrite": {
"method": "mutation",
"group": "graphql",
"weight": 213,
"weight": 189,
"cookies": false,
"type": "graphql",
"demo": "graphql\/mutation.md",
@@ -8240,7 +8240,7 @@
"x-appwrite": {
"method": "createSubscriber",
"group": "subscribers",
"weight": 261,
"weight": 239,
"cookies": false,
"type": "",
"demo": "messaging\/create-subscriber.md",
@@ -8325,7 +8325,7 @@
"x-appwrite": {
"method": "deleteSubscriber",
"group": "subscribers",
"weight": 265,
"weight": 243,
"cookies": false,
"type": "",
"demo": "messaging\/delete-subscriber.md",
@@ -8396,7 +8396,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 526,
"weight": 529,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@@ -8489,7 +8489,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 524,
"weight": 527,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@@ -8580,7 +8580,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 525,
"weight": 528,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@@ -8651,7 +8651,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 527,
"weight": 530,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@@ -8742,7 +8742,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 528,
"weight": 531,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@@ -8813,7 +8813,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 530,
"weight": 533,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@@ -8893,7 +8893,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 529,
"weight": 532,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@@ -9101,7 +9101,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 531,
"weight": 534,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@@ -9181,7 +9181,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 427,
"weight": 405,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@@ -9251,7 +9251,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 423,
"weight": 401,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@@ -9325,7 +9325,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 424,
"weight": 402,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@@ -9391,7 +9391,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 425,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@@ -9473,7 +9473,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 426,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@@ -9541,7 +9541,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 428,
"weight": 406,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@@ -9625,7 +9625,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 419,
"weight": 397,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@@ -9728,7 +9728,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 411,
"weight": 389,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@@ -9882,7 +9882,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 412,
"weight": 390,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@@ -9984,7 +9984,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 415,
"weight": 393,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@@ -10130,7 +10130,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 413,
"weight": 391,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@@ -10239,7 +10239,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 417,
"weight": 395,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@@ -10339,7 +10339,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 422,
"weight": 400,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@@ -10461,7 +10461,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 421,
"weight": 399,
"cookies": false,
"type": "",
"demo": "tablesdb\/increment-row-column.md",
@@ -10581,7 +10581,7 @@
"x-appwrite": {
"method": "list",
"group": "teams",
"weight": 134,
"weight": 110,
"cookies": false,
"type": "",
"demo": "teams\/list.md",
@@ -10666,7 +10666,7 @@
"x-appwrite": {
"method": "create",
"group": "teams",
"weight": 133,
"weight": 109,
"cookies": false,
"type": "",
"demo": "teams\/create.md",
@@ -10757,7 +10757,7 @@
"x-appwrite": {
"method": "get",
"group": "teams",
"weight": 135,
"weight": 111,
"cookies": false,
"type": "",
"demo": "teams\/get.md",
@@ -10820,7 +10820,7 @@
"x-appwrite": {
"method": "updateName",
"group": "teams",
"weight": 137,
"weight": 113,
"cookies": false,
"type": "",
"demo": "teams\/update-name.md",
@@ -10896,7 +10896,7 @@
"x-appwrite": {
"method": "delete",
"group": "teams",
"weight": 139,
"weight": 115,
"cookies": false,
"type": "",
"demo": "teams\/delete.md",
@@ -10959,7 +10959,7 @@
"x-appwrite": {
"method": "listMemberships",
"group": "memberships",
"weight": 141,
"weight": 117,
"cookies": false,
"type": "",
"demo": "teams\/list-memberships.md",
@@ -11052,7 +11052,7 @@
"x-appwrite": {
"method": "createMembership",
"group": "memberships",
"weight": 140,
"weight": 116,
"cookies": false,
"type": "",
"demo": "teams\/create-membership.md",
@@ -11176,7 +11176,7 @@
"x-appwrite": {
"method": "getMembership",
"group": "memberships",
"weight": 142,
"weight": 118,
"cookies": false,
"type": "",
"demo": "teams\/get-membership.md",
@@ -11247,7 +11247,7 @@
"x-appwrite": {
"method": "updateMembership",
"group": "memberships",
"weight": 143,
"weight": 119,
"cookies": false,
"type": "",
"demo": "teams\/update-membership.md",
@@ -11341,7 +11341,7 @@
"x-appwrite": {
"method": "deleteMembership",
"group": "memberships",
"weight": 145,
"weight": 121,
"cookies": false,
"type": "",
"demo": "teams\/delete-membership.md",
@@ -11414,7 +11414,7 @@
"x-appwrite": {
"method": "updateMembershipStatus",
"group": "memberships",
"weight": 144,
"weight": 120,
"cookies": false,
"type": "",
"demo": "teams\/update-membership-status.md",
@@ -11510,7 +11510,7 @@
"x-appwrite": {
"method": "getPrefs",
"group": "teams",
"weight": 136,
"weight": 112,
"cookies": false,
"type": "",
"demo": "teams\/get-prefs.md",
@@ -11573,7 +11573,7 @@
"x-appwrite": {
"method": "updatePrefs",
"group": "teams",
"weight": 138,
"weight": 114,
"cookies": false,
"type": "",
"demo": "teams\/update-prefs.md",
@@ -13393,6 +13393,16 @@
"description": "Total number of chunks uploaded",
"x-example": 17890,
"format": "int32"
},
"encryption": {
"type": "boolean",
"description": "Whether file contents are encrypted at rest.",
"x-example": true
},
"compression": {
"type": "string",
"description": "Compression algorithm used for the file. Will be one of none, [gzip](https:\/\/en.wikipedia.org\/wiki\/Gzip), or [zstd](https:\/\/en.wikipedia.org\/wiki\/Zstd).",
"x-example": "gzip"
}
},
"required": [
@@ -13406,7 +13416,9 @@
"mimeType",
"sizeOriginal",
"chunksTotal",
"chunksUploaded"
"chunksUploaded",
"encryption",
"compression"
],
"example": {
"$id": "5e5ea5c16897e",
@@ -13421,7 +13433,9 @@
"mimeType": "image\/png",
"sizeOriginal": 17890,
"chunksTotal": 17890,
"chunksUploaded": 17890
"chunksUploaded": 17890,
"encryption": true,
"compression": "gzip"
}
},
"team": {
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+74 -74
View File
@@ -612,7 +612,7 @@
"x-appwrite": {
"method": "updateMFA",
"group": "mfa",
"weight": 277,
"weight": 255,
"cookies": false,
"type": "",
"demo": "account\/update-mfa.md",
@@ -687,7 +687,7 @@
"x-appwrite": {
"method": "createMfaAuthenticator",
"group": "mfa",
"weight": 279,
"weight": 257,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-authenticator.md",
@@ -811,7 +811,7 @@
"x-appwrite": {
"method": "updateMfaAuthenticator",
"group": "mfa",
"weight": 280,
"weight": 258,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-authenticator.md",
@@ -952,7 +952,7 @@
"x-appwrite": {
"method": "deleteMfaAuthenticator",
"group": "mfa",
"weight": 281,
"weight": 259,
"cookies": false,
"type": "",
"demo": "account\/delete-mfa-authenticator.md",
@@ -1076,7 +1076,7 @@
"x-appwrite": {
"method": "createMfaChallenge",
"group": "mfa",
"weight": 285,
"weight": 263,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-challenge.md",
@@ -1213,7 +1213,7 @@
"x-appwrite": {
"method": "updateMfaChallenge",
"group": "mfa",
"weight": 286,
"weight": 264,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-challenge.md",
@@ -1353,7 +1353,7 @@
"x-appwrite": {
"method": "listMfaFactors",
"group": "mfa",
"weight": 278,
"weight": 256,
"cookies": false,
"type": "",
"demo": "account\/list-mfa-factors.md",
@@ -1454,7 +1454,7 @@
"x-appwrite": {
"method": "getMfaRecoveryCodes",
"group": "mfa",
"weight": 284,
"weight": 262,
"cookies": false,
"type": "",
"demo": "account\/get-mfa-recovery-codes.md",
@@ -1555,7 +1555,7 @@
"x-appwrite": {
"method": "createMfaRecoveryCodes",
"group": "mfa",
"weight": 282,
"weight": 260,
"cookies": false,
"type": "",
"demo": "account\/create-mfa-recovery-codes.md",
@@ -1656,7 +1656,7 @@
"x-appwrite": {
"method": "updateMfaRecoveryCodes",
"group": "mfa",
"weight": 283,
"weight": 261,
"cookies": false,
"type": "",
"demo": "account\/update-mfa-recovery-codes.md",
@@ -4203,7 +4203,7 @@
"x-appwrite": {
"method": "getBrowser",
"group": null,
"weight": 288,
"weight": 266,
"cookies": false,
"type": "location",
"demo": "avatars\/get-browser.md",
@@ -4329,7 +4329,7 @@
"x-appwrite": {
"method": "getCreditCard",
"group": null,
"weight": 287,
"weight": 265,
"cookies": false,
"type": "location",
"demo": "avatars\/get-credit-card.md",
@@ -4461,7 +4461,7 @@
"x-appwrite": {
"method": "getFavicon",
"group": null,
"weight": 291,
"weight": 269,
"cookies": false,
"type": "location",
"demo": "avatars\/get-favicon.md",
@@ -4525,7 +4525,7 @@
"x-appwrite": {
"method": "getFlag",
"group": null,
"weight": 289,
"weight": 267,
"cookies": false,
"type": "location",
"demo": "avatars\/get-flag.md",
@@ -5013,7 +5013,7 @@
"x-appwrite": {
"method": "getImage",
"group": null,
"weight": 290,
"weight": 268,
"cookies": false,
"type": "location",
"demo": "avatars\/get-image.md",
@@ -5097,7 +5097,7 @@
"x-appwrite": {
"method": "getInitials",
"group": null,
"weight": 293,
"weight": 271,
"cookies": false,
"type": "location",
"demo": "avatars\/get-initials.md",
@@ -5189,7 +5189,7 @@
"x-appwrite": {
"method": "getQR",
"group": null,
"weight": 292,
"weight": 270,
"cookies": false,
"type": "location",
"demo": "avatars\/get-qr.md",
@@ -5281,7 +5281,7 @@
"x-appwrite": {
"method": "getScreenshot",
"group": null,
"weight": 294,
"weight": 272,
"cookies": false,
"type": "location",
"demo": "avatars\/get-screenshot.md",
@@ -5994,7 +5994,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 362,
"weight": 340,
"cookies": false,
"type": "",
"demo": "databases\/list-transactions.md",
@@ -6061,7 +6061,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 358,
"weight": 336,
"cookies": false,
"type": "",
"demo": "databases\/create-transaction.md",
@@ -6132,7 +6132,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 359,
"weight": 337,
"cookies": false,
"type": "",
"demo": "databases\/get-transaction.md",
@@ -6195,7 +6195,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 360,
"weight": 338,
"cookies": false,
"type": "",
"demo": "databases\/update-transaction.md",
@@ -6274,7 +6274,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 361,
"weight": 339,
"cookies": false,
"type": "",
"demo": "databases\/delete-transaction.md",
@@ -6339,7 +6339,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 363,
"weight": 341,
"cookies": false,
"type": "",
"demo": "databases\/create-operations.md",
@@ -6420,7 +6420,7 @@
"x-appwrite": {
"method": "listDocuments",
"group": "documents",
"weight": 321,
"weight": 299,
"cookies": false,
"type": "",
"demo": "databases\/list-documents.md",
@@ -6524,7 +6524,7 @@
"x-appwrite": {
"method": "createDocument",
"group": "documents",
"weight": 313,
"weight": 291,
"cookies": false,
"type": "",
"demo": "databases\/create-document.md",
@@ -6683,7 +6683,7 @@
"x-appwrite": {
"method": "getDocument",
"group": "documents",
"weight": 314,
"weight": 292,
"cookies": false,
"type": "",
"demo": "databases\/get-document.md",
@@ -6786,7 +6786,7 @@
"x-appwrite": {
"method": "upsertDocument",
"group": "documents",
"weight": 317,
"weight": 295,
"cookies": false,
"type": "",
"demo": "databases\/upsert-document.md",
@@ -6937,7 +6937,7 @@
"x-appwrite": {
"method": "updateDocument",
"group": "documents",
"weight": 315,
"weight": 293,
"cookies": false,
"type": "",
"demo": "databases\/update-document.md",
@@ -7047,7 +7047,7 @@
"x-appwrite": {
"method": "deleteDocument",
"group": "documents",
"weight": 319,
"weight": 297,
"cookies": false,
"type": "",
"demo": "databases\/delete-document.md",
@@ -7148,7 +7148,7 @@
"x-appwrite": {
"method": "decrementDocumentAttribute",
"group": "documents",
"weight": 324,
"weight": 302,
"cookies": false,
"type": "",
"demo": "databases\/decrement-document-attribute.md",
@@ -7271,7 +7271,7 @@
"x-appwrite": {
"method": "incrementDocumentAttribute",
"group": "documents",
"weight": 323,
"weight": 301,
"cookies": false,
"type": "",
"demo": "databases\/increment-document-attribute.md",
@@ -7392,7 +7392,7 @@
"x-appwrite": {
"method": "listExecutions",
"group": "executions",
"weight": 455,
"weight": 433,
"cookies": false,
"type": "",
"demo": "functions\/list-executions.md",
@@ -7475,7 +7475,7 @@
"x-appwrite": {
"method": "createExecution",
"group": "executions",
"weight": 453,
"weight": 431,
"cookies": false,
"type": "",
"demo": "functions\/create-execution.md",
@@ -7594,7 +7594,7 @@
"x-appwrite": {
"method": "getExecution",
"group": "executions",
"weight": 454,
"weight": 432,
"cookies": false,
"type": "",
"demo": "functions\/get-execution.md",
@@ -7666,7 +7666,7 @@
"x-appwrite": {
"method": "query",
"group": "graphql",
"weight": 214,
"weight": 190,
"cookies": false,
"type": "graphql",
"demo": "graphql\/query.md",
@@ -7741,7 +7741,7 @@
"x-appwrite": {
"method": "mutation",
"group": "graphql",
"weight": 213,
"weight": 189,
"cookies": false,
"type": "graphql",
"demo": "graphql\/mutation.md",
@@ -8240,7 +8240,7 @@
"x-appwrite": {
"method": "createSubscriber",
"group": "subscribers",
"weight": 261,
"weight": 239,
"cookies": false,
"type": "",
"demo": "messaging\/create-subscriber.md",
@@ -8325,7 +8325,7 @@
"x-appwrite": {
"method": "deleteSubscriber",
"group": "subscribers",
"weight": 265,
"weight": 243,
"cookies": false,
"type": "",
"demo": "messaging\/delete-subscriber.md",
@@ -8396,7 +8396,7 @@
"x-appwrite": {
"method": "listFiles",
"group": "files",
"weight": 526,
"weight": 529,
"cookies": false,
"type": "",
"demo": "storage\/list-files.md",
@@ -8489,7 +8489,7 @@
"x-appwrite": {
"method": "createFile",
"group": "files",
"weight": 524,
"weight": 527,
"cookies": false,
"type": "upload",
"demo": "storage\/create-file.md",
@@ -8580,7 +8580,7 @@
"x-appwrite": {
"method": "getFile",
"group": "files",
"weight": 525,
"weight": 528,
"cookies": false,
"type": "",
"demo": "storage\/get-file.md",
@@ -8651,7 +8651,7 @@
"x-appwrite": {
"method": "updateFile",
"group": "files",
"weight": 527,
"weight": 530,
"cookies": false,
"type": "",
"demo": "storage\/update-file.md",
@@ -8742,7 +8742,7 @@
"x-appwrite": {
"method": "deleteFile",
"group": "files",
"weight": 528,
"weight": 531,
"cookies": false,
"type": "",
"demo": "storage\/delete-file.md",
@@ -8813,7 +8813,7 @@
"x-appwrite": {
"method": "getFileDownload",
"group": "files",
"weight": 530,
"weight": 533,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-download.md",
@@ -8893,7 +8893,7 @@
"x-appwrite": {
"method": "getFilePreview",
"group": "files",
"weight": 529,
"weight": 532,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-preview.md",
@@ -9101,7 +9101,7 @@
"x-appwrite": {
"method": "getFileView",
"group": "files",
"weight": 531,
"weight": 534,
"cookies": false,
"type": "location",
"demo": "storage\/get-file-view.md",
@@ -9181,7 +9181,7 @@
"x-appwrite": {
"method": "listTransactions",
"group": "transactions",
"weight": 427,
"weight": 405,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-transactions.md",
@@ -9251,7 +9251,7 @@
"x-appwrite": {
"method": "createTransaction",
"group": "transactions",
"weight": 423,
"weight": 401,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-transaction.md",
@@ -9325,7 +9325,7 @@
"x-appwrite": {
"method": "getTransaction",
"group": "transactions",
"weight": 424,
"weight": 402,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-transaction.md",
@@ -9391,7 +9391,7 @@
"x-appwrite": {
"method": "updateTransaction",
"group": "transactions",
"weight": 425,
"weight": 403,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-transaction.md",
@@ -9473,7 +9473,7 @@
"x-appwrite": {
"method": "deleteTransaction",
"group": "transactions",
"weight": 426,
"weight": 404,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-transaction.md",
@@ -9541,7 +9541,7 @@
"x-appwrite": {
"method": "createOperations",
"group": "transactions",
"weight": 428,
"weight": 406,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-operations.md",
@@ -9625,7 +9625,7 @@
"x-appwrite": {
"method": "listRows",
"group": "rows",
"weight": 419,
"weight": 397,
"cookies": false,
"type": "",
"demo": "tablesdb\/list-rows.md",
@@ -9728,7 +9728,7 @@
"x-appwrite": {
"method": "createRow",
"group": "rows",
"weight": 411,
"weight": 389,
"cookies": false,
"type": "",
"demo": "tablesdb\/create-row.md",
@@ -9882,7 +9882,7 @@
"x-appwrite": {
"method": "getRow",
"group": "rows",
"weight": 412,
"weight": 390,
"cookies": false,
"type": "",
"demo": "tablesdb\/get-row.md",
@@ -9984,7 +9984,7 @@
"x-appwrite": {
"method": "upsertRow",
"group": "rows",
"weight": 415,
"weight": 393,
"cookies": false,
"type": "",
"demo": "tablesdb\/upsert-row.md",
@@ -10130,7 +10130,7 @@
"x-appwrite": {
"method": "updateRow",
"group": "rows",
"weight": 413,
"weight": 391,
"cookies": false,
"type": "",
"demo": "tablesdb\/update-row.md",
@@ -10239,7 +10239,7 @@
"x-appwrite": {
"method": "deleteRow",
"group": "rows",
"weight": 417,
"weight": 395,
"cookies": false,
"type": "",
"demo": "tablesdb\/delete-row.md",
@@ -10339,7 +10339,7 @@
"x-appwrite": {
"method": "decrementRowColumn",
"group": "rows",
"weight": 422,
"weight": 400,
"cookies": false,
"type": "",
"demo": "tablesdb\/decrement-row-column.md",
@@ -10461,7 +10461,7 @@
"x-appwrite": {
"method": "incrementRowColumn",
"group": "rows",
"weight": 421,
"weight": 399,
"cookies": false,
"type": "",
"demo": "tablesdb\/increment-row-column.md",
@@ -10581,7 +10581,7 @@
"x-appwrite": {
"method": "list",
"group": "teams",
"weight": 134,
"weight": 110,
"cookies": false,
"type": "",
"demo": "teams\/list.md",
@@ -10666,7 +10666,7 @@
"x-appwrite": {
"method": "create",
"group": "teams",
"weight": 133,
"weight": 109,
"cookies": false,
"type": "",
"demo": "teams\/create.md",
@@ -10757,7 +10757,7 @@
"x-appwrite": {
"method": "get",
"group": "teams",
"weight": 135,
"weight": 111,
"cookies": false,
"type": "",
"demo": "teams\/get.md",
@@ -10820,7 +10820,7 @@
"x-appwrite": {
"method": "updateName",
"group": "teams",
"weight": 137,
"weight": 113,
"cookies": false,
"type": "",
"demo": "teams\/update-name.md",
@@ -10896,7 +10896,7 @@
"x-appwrite": {
"method": "delete",
"group": "teams",
"weight": 139,
"weight": 115,
"cookies": false,
"type": "",
"demo": "teams\/delete.md",
@@ -10959,7 +10959,7 @@
"x-appwrite": {
"method": "listMemberships",
"group": "memberships",
"weight": 141,
"weight": 117,
"cookies": false,
"type": "",
"demo": "teams\/list-memberships.md",
@@ -11052,7 +11052,7 @@
"x-appwrite": {
"method": "createMembership",
"group": "memberships",
"weight": 140,
"weight": 116,
"cookies": false,
"type": "",
"demo": "teams\/create-membership.md",
@@ -11176,7 +11176,7 @@
"x-appwrite": {
"method": "getMembership",
"group": "memberships",
"weight": 142,
"weight": 118,
"cookies": false,
"type": "",
"demo": "teams\/get-membership.md",
@@ -11247,7 +11247,7 @@
"x-appwrite": {
"method": "updateMembership",
"group": "memberships",
"weight": 143,
"weight": 119,
"cookies": false,
"type": "",
"demo": "teams\/update-membership.md",
@@ -11341,7 +11341,7 @@
"x-appwrite": {
"method": "deleteMembership",
"group": "memberships",
"weight": 145,
"weight": 121,
"cookies": false,
"type": "",
"demo": "teams\/delete-membership.md",
@@ -11414,7 +11414,7 @@
"x-appwrite": {
"method": "updateMembershipStatus",
"group": "memberships",
"weight": 144,
"weight": 120,
"cookies": false,
"type": "",
"demo": "teams\/update-membership-status.md",
@@ -11510,7 +11510,7 @@
"x-appwrite": {
"method": "getPrefs",
"group": "teams",
"weight": 136,
"weight": 112,
"cookies": false,
"type": "",
"demo": "teams\/get-prefs.md",
@@ -11573,7 +11573,7 @@
"x-appwrite": {
"method": "updatePrefs",
"group": "teams",
"weight": 138,
"weight": 114,
"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
+269
View File
@@ -26,6 +26,7 @@ use Utopia\Migration\Resource;
use Utopia\Migration\Sources\Appwrite;
use Utopia\Migration\Sources\CSV;
use Utopia\Migration\Sources\Firebase;
use Utopia\Migration\Sources\JSON;
use Utopia\Migration\Sources\NHost;
use Utopia\Migration\Sources\Supabase;
use Utopia\Migration\Transfer;
@@ -596,6 +597,274 @@ App::post('/v1/migrations/csv/exports')
->dynamic($migration, Response::MODEL_MIGRATION);
});
App::post('/v1/migrations/json/imports')
->groups(['api', 'migrations'])
->desc('Import documents from a JSON')
->label('scope', 'migrations.write')
->label('event', 'migrations.[migrationId].create')
->label('audits.event', 'migration.create')
->label('sdk', new Method(
namespace: 'migrations',
group: null,
name: 'createJSONImport',
description: '/docs/references/migrations/migration-json-import.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_ACCEPTED,
model: Response::MODEL_MIGRATION,
)
]
))
->param('bucketId', '', new UID(), 'Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).')
->param('fileId', '', new UID(), 'File ID.')
->param('resourceId', null, new CompoundUID(), 'Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.')
->param('internalFile', false, new Boolean(), 'Is the file stored in an internal bucket?', true)
->inject('response')
->inject('dbForProject')
->inject('dbForPlatform')
->inject('authorization')
->inject('project')
->inject('platform')
->inject('deviceForFiles')
->inject('deviceForMigrations')
->inject('queueForEvents')
->inject('queueForMigrations')
->action(function (
string $bucketId,
string $fileId,
string $resourceId,
bool $internalFile,
Response $response,
Database $dbForProject,
Database $dbForPlatform,
Authorization $authorization,
Document $project,
array $platform,
Device $deviceForFiles,
Device $deviceForMigrations,
Event $queueForEvents,
Migration $queueForMigrations
) {
$bucket = $authorization->skip(function () use ($internalFile, $dbForPlatform, $dbForProject, $bucketId) {
if ($internalFile) {
return $dbForPlatform->getDocument('buckets', 'default');
}
return $dbForProject->getDocument('buckets', $bucketId);
});
if ($bucket->isEmpty()) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
$file = $authorization->skip(fn () => $internalFile ? $dbForPlatform->getDocument('bucket_' . $bucket->getSequence(), $fileId) : $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
if ($file->isEmpty()) {
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
}
$path = $file->getAttribute('path', '');
if (!$deviceForFiles->exists($path)) {
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND, 'File not found in ' . $path);
}
// No encryption or compression on files above 20MB.
$hasEncryption = !empty($file->getAttribute('openSSLCipher'));
$compression = $file->getAttribute('algorithm', Compression::NONE);
$hasCompression = $compression !== Compression::NONE;
$migrationId = ID::unique();
$newPath = $deviceForMigrations->getPath($migrationId . '_' . $fileId . '.json');
if ($hasEncryption || $hasCompression) {
$source = $deviceForFiles->read($path);
if ($hasEncryption) {
$source = OpenSSL::decrypt(
$source,
$file->getAttribute('openSSLCipher'),
System::getEnv('_APP_OPENSSL_KEY_V' . $file->getAttribute('openSSLVersion')),
0,
hex2bin($file->getAttribute('openSSLIV')),
hex2bin($file->getAttribute('openSSLTag'))
);
}
if ($hasCompression) {
switch ($compression) {
case Compression::ZSTD:
$source = (new Zstd())->decompress($source);
break;
case Compression::GZIP:
$source = (new GZIP())->decompress($source);
break;
}
}
// Manual write after decryption and/or decompression
if (!$deviceForMigrations->write($newPath, $source, 'application/json')) {
throw new \Exception('Unable to copy file');
}
} elseif (!$deviceForFiles->transfer($path, $newPath, $deviceForMigrations)) {
throw new \Exception('Unable to copy file');
}
$fileSize = $deviceForMigrations->getFileSize($newPath);
$resources = Transfer::extractServices([Transfer::GROUP_DATABASES]);
$migration = $dbForProject->createDocument('migrations', new Document([
'$id' => $migrationId,
'status' => 'pending',
'stage' => 'init',
'source' => JSON::getName(),
'destination' => Appwrite::getName(),
'resources' => $resources,
'resourceId' => $resourceId,
'resourceType' => Resource::TYPE_DATABASE,
'statusCounters' => '{}',
'resourceData' => '{}',
'errors' => [],
'options' => [
'path' => $newPath,
'size' => $fileSize,
],
]));
$queueForEvents->setParam('migrationId', $migration->getId());
$queueForMigrations
->setMigration($migration)
->setProject($project)
->setProject($project)
->trigger();
$response
->setStatusCode(Response::STATUS_CODE_ACCEPTED)
->dynamic($migration, Response::MODEL_MIGRATION);
});
App::post('/v1/migrations/json/exports')
->groups(['api', 'migrations'])
->desc('Export documents to JSON')
->label('scope', 'migrations.write')
->label('event', 'migrations.[migrationId].create')
->label('audits.event', 'migration.create')
->label('sdk', new Method(
namespace: 'migrations',
group: null,
name: 'createJSONExport',
description: '/docs/references/migrations/migration-json-export.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_ACCEPTED,
model: Response::MODEL_MIGRATION,
)
]
))
->param('resourceId', null, new CompoundUID(), 'Composite ID in the format {databaseId:collectionId}, identifying a collection within a database to export.')
->param('filename', '', new Text(255), 'The name of the file to be created for the export, excluding the .json extension.')
->param('columns', [], new ArrayList(new Text(Database::LENGTH_KEY)), 'List of attributes to export. If empty, all attributes will be exported. You can use the `*` wildcard to export all attributes from the collection.', true)
->param('queries', [], new ArrayList(new Text(0)), 'Array of query strings generated using the Query class provided by the SDK to filter documents to export. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->param('notify', true, new Boolean(), 'Set to true to receive an email when the export is complete. Default is true.', true)
->inject('user')
->inject('response')
->inject('dbForProject')
->inject('dbForPlatform')
->inject('authorization')
->inject('project')
->inject('platform')
->inject('queueForEvents')
->inject('queueForMigrations')
->action(function (
string $resourceId,
string $filename,
array $columns,
array $queries,
bool $notify,
Document $user,
Response $response,
Database $dbForProject,
Database $dbForPlatform,
Authorization $authorization,
Document $project,
array $platform,
Event $queueForEvents,
Migration $queueForMigrations
) {
try {
$parsedQueries = Query::parseQueries($queries);
} catch (QueryException $e) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
}
$bucket = $authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'default'));
if ($bucket->isEmpty()) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
}
[$databaseId, $collectionId] = \explode(':', $resourceId, 2);
if (empty($databaseId)) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
if (empty($collectionId)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
if ($database->isEmpty()) {
throw new Exception(Exception::DATABASE_NOT_FOUND);
}
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
if ($collection->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
}
$validator = new Documents(
attributes: $collection->getAttribute('attributes', []),
indexes: $collection->getAttribute('indexes', []),
idAttributeType: $dbForProject->getAdapter()->getIdAttributeType(),
);
if (!$validator->isValid($parsedQueries)) {
throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription());
}
$migration = $dbForProject->createDocument('migrations', new Document([
'$id' => ID::unique(),
'status' => 'pending',
'stage' => 'init',
'source' => Appwrite::getName(),
'destination' => JSON::getName(),
'resources' => Transfer::extractServices([Transfer::GROUP_DATABASES]),
'resourceId' => $resourceId,
'resourceType' => Resource::TYPE_DATABASE,
'statusCounters' => '{}',
'resourceData' => '{}',
'errors' => [],
'options' => [
'bucketId' => 'default', // Always use internal bucket
'filename' => $filename,
'columns' => $columns,
'queries' => $queries,
'notify' => $notify,
'userInternalId' => $user->getSequence(),
],
]));
$queueForEvents->setParam('migrationId', $migration->getId());
$queueForMigrations
->setMigration($migration)
->setProject($project)
->setPlatform($platform)
->trigger();
$response
->setStatusCode(Response::STATUS_CODE_ACCEPTED)
->dynamic($migration, Response::MODEL_MIGRATION);
});
App::get('/v1/migrations')
->groups(['api', 'migrations'])
->desc('List migrations')
+7 -7
View File
@@ -47,19 +47,19 @@
"appwrite/php-clamav": "2.0.*",
"utopia-php/abuse": "1.*",
"utopia-php/analytics": "0.10.*",
"utopia-php/audit": "2.*",
"utopia-php/audit": "1.*",
"utopia-php/auth": "0.5.*",
"utopia-php/cache": "0.13.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "1.*",
"utopia-php/config": "1.*.*",
"utopia-php/database": "4.*",
"utopia-php/detector": "0.2.*",
"utopia-php/domains": "0.11.*",
"utopia-php/domains": "0.9.*",
"utopia-php/emails": "0.6.*",
"utopia-php/dns": "1.5.*",
"utopia-php/dns": "1.4.*",
"utopia-php/dsn": "0.2.1",
"utopia-php/framework": "0.33.*",
"utopia-php/fetch": "0.5.*",
"utopia-php/fetch": "0.4.*",
"utopia-php/image": "0.8.*",
"utopia-php/locale": "0.8.*",
"utopia-php/logger": "0.6.*",
@@ -69,10 +69,10 @@
"utopia-php/platform": "0.7.*",
"utopia-php/pools": "0.8.*",
"utopia-php/preloader": "0.2.*",
"utopia-php/queue": "0.15.*",
"utopia-php/queue": "0.11.*",
"utopia-php/registry": "0.5.*",
"utopia-php/storage": "0.18.*",
"utopia-php/swoole": "1.*",
"utopia-php/swoole": "0.8.*",
"utopia-php/system": "0.9.*",
"utopia-php/telemetry": "0.1.*",
"utopia-php/vcs": "0.13.*",
Generated
+71 -8
View File
@@ -798,6 +798,68 @@
},
"time": "2026-01-12T17:58:43+00:00"
},
{
"name": "halaxa/json-machine",
"version": "1.2.6",
"source": {
"type": "git",
"url": "https://github.com/halaxa/json-machine.git",
"reference": "8bf0b0ff6ff60ab480778eaa5ad7d505b442c2d4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/halaxa/json-machine/zipball/8bf0b0ff6ff60ab480778eaa5ad7d505b442c2d4",
"reference": "8bf0b0ff6ff60ab480778eaa5ad7d505b442c2d4",
"shasum": ""
},
"require": {
"php": "7.2 - 8.5"
},
"require-dev": {
"ext-json": "*",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^8.0"
},
"suggest": {
"ext-json": "To run JSON Machine out of the box without custom decoders.",
"guzzlehttp/guzzle": "To run example with GuzzleHttp"
},
"type": "library",
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"JsonMachine\\": "src/"
},
"exclude-from-classmap": [
"src/autoloader.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Filip Halaxa",
"email": "filip@halaxa.cz"
}
],
"description": "Efficient, easy-to-use and fast JSON pull parser",
"support": {
"issues": "https://github.com/halaxa/json-machine/issues",
"source": "https://github.com/halaxa/json-machine/tree/1.2.6"
},
"funding": [
{
"url": "https://ko-fi.com/G2G57KTE4",
"type": "other"
}
],
"time": "2025-12-05T14:53:09+00:00"
},
{
"name": "league/csv",
"version": "9.24.1",
@@ -4516,22 +4578,23 @@
},
{
"name": "utopia-php/migration",
"version": "1.4.4",
"version": "1.4.6",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/migration.git",
"reference": "3fe751902012d09d323420cd3523be1ed855e868"
"reference": "f358db6fb6a01d855bbed39e283387069e4f277d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/3fe751902012d09d323420cd3523be1ed855e868",
"reference": "3fe751902012d09d323420cd3523be1ed855e868",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/f358db6fb6a01d855bbed39e283387069e4f277d",
"reference": "f358db6fb6a01d855bbed39e283387069e4f277d",
"shasum": ""
},
"require": {
"appwrite/appwrite": "19.*",
"ext-curl": "*",
"ext-openssl": "*",
"halaxa/json-machine": "^1.2",
"php": ">=8.1",
"utopia-php/console": "0.0.*",
"utopia-php/database": "4.*",
@@ -4565,9 +4628,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/1.4.4"
"source": "https://github.com/utopia-php/migration/tree/1.4.6"
},
"time": "2026-01-16T10:00:07+00:00"
"time": "2026-01-20T11:07:17+00:00"
},
{
"name": "utopia-php/mongo",
@@ -8988,7 +9051,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@@ -9012,5 +9075,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.2.0"
"plugin-api-version": "2.6.0"
}
@@ -0,0 +1 @@
Get the number of audits that are waiting to be processed in the Appwrite internal queue server.
@@ -0,0 +1 @@
Export documents to a JSON file from your Appwrite database. This endpoint allows you to export documents to a JSON file stored in a secure internal bucket. You'll receive an email with a download link when the export is complete.
@@ -0,0 +1 @@
Import documents from a JSON file into your Appwrite database. This endpoint allows you to import documents from a JSON file uploaded to Appwrite Storage bucket.
+74 -50
View File
@@ -24,12 +24,14 @@ use Utopia\Locale\Locale;
use Utopia\Migration\Destination;
use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite;
use Utopia\Migration\Destinations\CSV as DestinationCSV;
use Utopia\Migration\Destinations\JSON as DestinationJSON;
use Utopia\Migration\Exception as MigrationException;
use Utopia\Migration\Source;
use Utopia\Migration\Sources\Appwrite;
use Utopia\Migration\Sources\Appwrite as SourceAppwrite;
use Utopia\Migration\Sources\CSV;
use Utopia\Migration\Sources\Firebase;
use Utopia\Migration\Sources\JSON;
use Utopia\Migration\Sources\NHost;
use Utopia\Migration\Sources\Supabase;
use Utopia\Migration\Transfer;
@@ -58,13 +60,16 @@ class Migrations extends Action
*/
protected $logError = null;
/* either CSV or JSON */
private string|null $dataExportType = null;
public static function getName(): string
{
return 'migrations';
}
/**
* @throws Exception
* @throws \Exception
*/
public function __construct()
{
@@ -85,7 +90,7 @@ class Migrations extends Action
}
/**
* @throws Exception
* @throws \Exception
*/
public function action(
Message $message,
@@ -135,30 +140,17 @@ class Migrations extends Action
return;
}
try {
$this->processMigration(
$migration,
$queueForRealtime,
$queueForMails,
$platform,
$authorization
);
} finally {
$this->dbForProject = null;
$this->dbForPlatform = null;
$this->project = null;
$this->logError = null;
$this->deviceForMigrations = null;
$this->deviceForFiles = null;
$this->plan = [];
$this->sourceReport = [];
\gc_collect_cycles();
}
$this->processMigration(
$migration,
$queueForRealtime,
$queueForMails,
$platform,
$authorization
);
}
/**
* @throws Exception
* @throws \Exception
*/
protected function processSource(Document $migration, array $platform): Source
{
@@ -171,7 +163,13 @@ class Migrations extends Action
$database = null;
$queries = [];
if ($source === Appwrite::getName() && $destination === DestinationCSV::getName()) {
$this->dataExportType = match ($destination) {
DestinationCSV::getName() => 'CSV',
DestinationJSON::getName() => 'JSON',
default => null /* there are other valid exports, so we don't throw */
};
if ($source === Appwrite::getName() && ($destination === DestinationCSV::getName() || $destination === DestinationJSON::getName())) {
$dataSource = Appwrite::SOURCE_DATABASE;
$database = $this->dbForProject;
$queries = Query::parseQueries($migrationOptions['queries']);
@@ -213,6 +211,12 @@ class Migrations extends Action
$this->deviceForMigrations,
$this->dbForProject
),
JSON::getName() => new JSON(
$resourceId,
$migrationOptions['path'],
$this->deviceForMigrations,
$this->dbForProject
),
default => throw new \Exception('Invalid source type'),
};
@@ -223,7 +227,7 @@ class Migrations extends Action
}
/**
* @throws Exception
* @throws \Exception
*/
protected function processDestination(Document $migration, string $apiKey, array $platform): Destination
{
@@ -251,6 +255,13 @@ class Migrations extends Action
$options['escape'],
$options['header'],
),
DestinationJSON::getName() => new DestinationJSON(
$this->deviceForFiles,
$migration->getAttribute('resourceId'),
$options['bucketId'],
$options['filename'],
$options['columns'],
),
default => throw new \Exception('Invalid destination type'),
};
}
@@ -260,7 +271,7 @@ class Migrations extends Action
* @throws Structure
* @throws Conflict
* @throws \Utopia\Database\Exception
* @throws Exception
* @throws \Exception
*/
protected function updateMigrationDocument(Document $migration, Document $project, Realtime $queueForRealtime): Document
{
@@ -280,7 +291,7 @@ class Migrations extends Action
}
/**
* @throws Exception
* @throws \Exception
*/
protected function generateAPIKey(Document $project): string
{
@@ -320,7 +331,7 @@ class Migrations extends Action
* @throws Restricted
* @throws Structure
* @throws \Utopia\Database\Exception
* @throws Exception
* @throws \Exception
*/
protected function processMigration(
Document $migration,
@@ -444,9 +455,17 @@ class Migrations extends Action
$destination?->success();
$source?->success();
// TODO: Move to CSV hook
if ($migration->getAttribute('destination') === DestinationCSV::getName()) {
$this->handleCSVExportComplete($project, $migration, $queueForMails, $queueForRealtime, $platform, $authorization);
// TODO: Move to CSV|JSON hook
$destinationName = $migration->getAttribute('destination');
if ($destinationName === DestinationCSV::getName() || $destinationName === DestinationJSON::getName()) {
$this->handleDataExportComplete(
$project,
$migration,
$queueForMails,
$queueForRealtime,
$platform,
$authorization
);
}
}
} finally {
@@ -461,7 +480,7 @@ class Migrations extends Action
}
/**
* Handle actions to be performed when a CSV export migration is successfully completed
* Handle actions to be performed when a data export migration is successfully completed
*
* @param Document $project
* @param Document $migration
@@ -471,7 +490,7 @@ class Migrations extends Action
* @param Authorization $authorization
* @return void
*/
protected function handleCSVExportComplete(
protected function handleDataExportComplete(
Document $project,
Document $migration,
Mail $queueForMails,
@@ -496,7 +515,8 @@ class Migrations extends Action
throw new \Exception('Bucket not found');
}
$path = $this->deviceForFiles->getPath($bucketId . '/' . $this->sanitizeFilename($filename) . '.csv');
$ext = strtolower($this->dataExportType);
$path = $this->deviceForFiles->getPath($bucketId . '/' . $this->sanitizeFilename($filename) . '.' . $ext);
$size = $this->deviceForFiles->getFileSize($path);
$mime = $this->deviceForFiles->getFileMimeType($path);
$hash = $this->deviceForFiles->getFileHash($path);
@@ -521,7 +541,7 @@ class Migrations extends Action
Document::SET_TYPE_APPEND,
));
$this->sendCSVEmail(
$this->sendDataExportEmail(
success: false,
project: $project,
user: $user,
@@ -576,12 +596,12 @@ class Migrations extends Action
// Generate download URL with JWT
$endpoint = System::getEnv('_APP_DOMAIN', '');
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled' ? 'https' : 'http';
$downloadUrl = "{$protocol}://{$endpoint}/v1/storage/buckets/{$bucketId}/files/{$fileId}/push?project={$project->getId()}&jwt={$jwt}";
$downloadUrl = "$protocol://$endpoint/v1/storage/buckets/$bucketId/files/$fileId/push?project={$project->getId()}&jwt=$jwt";
$options['downloadUrl'] = $downloadUrl;
$migration->setAttribute('options', $options);
$this->updateMigrationDocument($migration, $project, $queueForRealtime);
$this->sendCSVEmail(
$this->sendDataExportEmail(
success: true,
project: $project,
user: $user,
@@ -593,7 +613,7 @@ class Migrations extends Action
}
/**
* Send CSV export notification email
* Send data export notification email
*
* @param bool $success Whether the export was successful
* @param Document $project
@@ -606,7 +626,7 @@ class Migrations extends Action
* @return void
* @throws \Exception
*/
protected function sendCSVEmail(
protected function sendDataExportEmail(
bool $success,
Document $project,
Document $user,
@@ -621,7 +641,7 @@ class Migrations extends Action
}
if ($user->isEmpty()) {
Console::warning("User not found for CSV export notification: {$user->getSequence()}");
Console::warning("User not found for $this->dataExportType export notification: {$user->getSequence()}");
return;
}
@@ -633,14 +653,14 @@ class Migrations extends Action
: 'failure';
// Get localized email content
$subject = $locale->getText("emails.csvExport.{$emailType}.subject");
$preview = $locale->getText("emails.csvExport.{$emailType}.preview");
$hello = $locale->getText("emails.csvExport.{$emailType}.hello");
$body = $locale->getText("emails.csvExport.{$emailType}.body");
$footer = $locale->getText("emails.csvExport.{$emailType}.footer");
$thanks = $locale->getText("emails.csvExport.{$emailType}.thanks");
$signature = $locale->getText("emails.csvExport.{$emailType}.signature");
$buttonText = $success ? $locale->getText("emails.csvExport.{$emailType}.buttonText") : '';
$subject = $locale->getText("emails.dataExport.$emailType.subject");
$preview = $locale->getText("emails.dataExport.$emailType.preview");
$hello = $locale->getText("emails.dataExport.$emailType.hello");
$body = $locale->getText("emails.dataExport.$emailType.body");
$footer = $locale->getText("emails.dataExport.$emailType.footer");
$thanks = $locale->getText("emails.dataExport.$emailType.thanks");
$signature = $locale->getText("emails.dataExport.$emailType.signature");
$buttonText = $success ? $locale->getText("emails.dataExport.$emailType.buttonText") : '';
// Build email body using appropriate template
$templatePath = $success
@@ -656,7 +676,10 @@ class Migrations extends Action
->setParam('{{direction}}', $locale->getText('settings.direction'))
->setParam('{{project}}', $project->getAttribute('name'))
->setParam('{{user}}', $user->getAttribute('name', $user->getAttribute('email')))
->setParam('{{size}}', $success ? '' : (string)$sizeMB);
->setParam('{{size}}', $success ? '' : (string)$sizeMB)
->setParam('{{type}}', $this->dataExportType)
->setParam('{{platform}}', $platform['platformName'])
;
if ($success) {
$message
@@ -676,6 +699,7 @@ class Migrations extends Action
'terms' => $platform['termsUrl'],
'privacy' => $platform['privacyUrl'],
'platform' => $platform['platformName'],
'type' => $this->dataExportType,
];
$queueForMails
@@ -689,7 +713,7 @@ class Migrations extends Action
->setSenderName($platform['emailSenderName'])
->trigger();
Console::info("CSV export {$emailType} notification email sent to " . $user->getAttribute('email'));
Console::info("$this->dataExportType export $emailType notification email sent to " . $user->getAttribute('email'));
}
/**
@@ -1355,4 +1355,429 @@ trait MigrationsBase
'x-appwrite-key' => $this->getProject()['apiKey']
]);
}
/**
* Import documents from a JSON file.
*/
public function testCreateJSONImport(): void
{
// Make a database
$response = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'Test Database'
]);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertEquals('Test Database', $response['body']['name']);
$databaseId = $response['body']['$id'];
// make a table
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test table',
'tableId' => ID::unique(),
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertEquals($response['body']['name'], 'Test table');
$tableId = $response['body']['$id'];
// make columns
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/string', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'name',
'size' => 256,
'required' => true,
]);
$this->assertEquals(202, $response['headers']['status-code']);
$this->assertEquals($response['body']['key'], 'name');
$this->assertEquals($response['body']['type'], 'string');
$this->assertEquals($response['body']['size'], 256);
$this->assertEquals($response['body']['required'], true);
$response = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $tableId . '/columns/integer', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'age',
'min' => 18,
'max' => 65,
'required' => true,
]);
$this->assertEquals(202, $response['headers']['status-code']);
$this->assertEquals($response['body']['key'], 'age');
$this->assertEquals($response['body']['type'], 'integer');
$this->assertEquals($response['body']['min'], 18);
$this->assertEquals($response['body']['max'], 65);
$this->assertEquals($response['body']['required'], true);
// make a bucket, upload a file to it!
$bucketOne = $this->client->call(Client::METHOD_POST, '/storage/buckets', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'bucketId' => ID::unique(),
'name' => 'Test Bucket',
'maximumFileSize' => 2000000, //2MB
'allowedFileExtensions' => ['json'],
'compression' => 'gzip',
'encryption' => true
]);
$this->assertEquals(201, $bucketOne['headers']['status-code']);
$this->assertNotEmpty($bucketOne['body']['$id']);
$bucketOneId = $bucketOne['body']['$id'];
$bucketIds = [
'default' => $bucketOneId,
'missing-column' => $bucketOneId,
'irrelevant-column' => $bucketOneId,
'documents-internals' => $bucketOneId,
];
$fileIds = [];
foreach ($bucketIds as $label => $bucketId) {
$jsonFileName = match ($label) {
'missing-column',
'irrelevant-column',
'documents-internals' => "$label.json",
default => 'documents.json',
};
$response = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'fileId' => ID::unique(),
'file' => new CURLFile(realpath(__DIR__ . '/../../../resources/json/'.$jsonFileName), 'application/json', $jsonFileName),
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertEquals($jsonFileName, $response['body']['name']);
$this->assertEquals('application/json', $response['body']['mimeType']);
$fileIds[$label] = $response['body']['$id'];
}
// missing column, fail in worker.
$missingColumn = $this->performJsonMigration(
[
'fileId' => $fileIds['missing-column'],
'bucketId' => $bucketIds['missing-column'],
'resourceId' => $databaseId . ':' . $tableId,
]
);
$this->assertEventually(function () use ($missingColumn) {
$migrationId = $missingColumn['body']['$id'];
$migration = $this->client->call(Client::METHOD_GET, '/migrations/'.$migrationId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $migration['headers']['status-code']);
$this->assertEquals('finished', $migration['body']['stage']);
$this->assertEquals('failed', $migration['body']['status']);
$this->assertEquals('JSON', $migration['body']['source']);
$this->assertEquals('Appwrite', $migration['body']['destination']);
$this->assertContains(Resource::TYPE_ROW, $migration['body']['resources']);
/* fails in batch create documents unlike csv which checks headers first! */
$this->assertArrayHasKey(Resource::TYPE_ROW, $migration['body']['statusCounters']);
$this->assertGreaterThan(0, $migration['body']['statusCounters'][Resource::TYPE_ROW]['error']);
$this->assertThat(
implode("\n", $migration['body']['errors']),
$this->stringContains('Missing required attribute')
);
$this->assertThat(
implode("\n", $migration['body']['errors']),
$this->stringContains('age')
);
}, 60_000, 500);
// irrelevant column - email, success.
$irrelevantColumn = $this->performJsonMigration(
[
'fileId' => $fileIds['irrelevant-column'],
'bucketId' => $bucketIds['irrelevant-column'],
'resourceId' => $databaseId . ':' . $tableId,
]
);
$this->assertEventually(function () use ($irrelevantColumn) {
$migrationId = $irrelevantColumn['body']['$id'];
$migration = $this->client->call(Client::METHOD_GET, '/migrations/'.$migrationId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $migration['headers']['status-code']);
$this->assertEquals('finished', $migration['body']['stage']);
$this->assertEquals('completed', $migration['body']['status']);
$this->assertEquals('JSON', $migration['body']['source']);
$this->assertEquals('Appwrite', $migration['body']['destination']);
$this->assertContains(Resource::TYPE_ROW, $migration['body']['resources']);
$this->assertArrayHasKey(Resource::TYPE_ROW, $migration['body']['statusCounters']);
$this->assertEquals(100, $migration['body']['statusCounters'][Resource::TYPE_ROW]['success']);
}, 10_000, 500);
// all data exists, pass.
$migration = $this->performJsonMigration(
[
'endpoint' => $this->endpoint,
'fileId' => $fileIds['default'],
'bucketId' => $bucketIds['default'],
'resourceId' => $databaseId . ':' . $tableId,
]
);
$this->assertEventually(function () use ($migration, $databaseId, $tableId) {
$migrationId = $migration['body']['$id'];
$migration = $this->client->call(Client::METHOD_GET, '/migrations/'.$migrationId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $migration['headers']['status-code']);
$this->assertEquals('finished', $migration['body']['stage']);
$this->assertEquals('completed', $migration['body']['status']);
$this->assertEquals('JSON', $migration['body']['source']);
$this->assertEquals('Appwrite', $migration['body']['destination']);
$this->assertContains(Resource::TYPE_ROW, $migration['body']['resources']);
$this->assertArrayHasKey(Resource::TYPE_ROW, $migration['body']['statusCounters']);
$this->assertEquals(100, $migration['body']['statusCounters'][Resource::TYPE_ROW]['success']);
}, 10_000, 500);
// get rows count
$rows = $this->client->call(Client::METHOD_GET, '/tablesdb/'.$databaseId.'/tables/'.$tableId.'/rows', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => [
Query::limit(250)->toString()
]
]);
$this->assertEquals(200, $rows['headers']['status-code']);
$this->assertIsArray($rows['body']['rows']);
$this->assertIsNumeric($rows['body']['total']);
$this->assertEquals(200, $rows['body']['total']);
// all data exists and includes internals, pass.
$migration = $this->performJsonMigration(
[
'endpoint' => $this->endpoint,
'fileId' => $fileIds['documents-internals'],
'bucketId' => $bucketIds['documents-internals'],
'resourceId' => $databaseId . ':' . $tableId,
]
);
$this->assertEventually(function () use ($migration) {
$migrationId = $migration['body']['$id'];
$migration = $this->client->call(Client::METHOD_GET, '/migrations/'.$migrationId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(200, $migration['headers']['status-code']);
$this->assertEquals('finished', $migration['body']['stage']);
$this->assertEquals('completed', $migration['body']['status']);
$this->assertEquals('JSON', $migration['body']['source']);
$this->assertEquals('Appwrite', $migration['body']['destination']);
$this->assertContains(Resource::TYPE_ROW, $migration['body']['resources']);
$this->assertArrayHasKey(Resource::TYPE_ROW, $migration['body']['statusCounters']);
$this->assertEquals(25, $migration['body']['statusCounters'][Resource::TYPE_ROW]['success']);
}, 10_000, 500);
}
private function performJsonMigration(array $body): array
{
return $this->client->call(Client::METHOD_POST, '/migrations/json/imports', [
'content-type' => 'application/json',
'x-appwrite-key' => $this->getProject()['apiKey'],
'x-appwrite-project' => $this->getProject()['$id'],
], $body);
}
/**
* Test JSON export with email notification
*/
public function testCreateJSONExport(): void
{
// Create a database
$database = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'Test Export Database'
]);
$this->assertEquals(201, $database['headers']['status-code']);
$databaseId = $database['body']['$id'];
// Create a collection
$collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'collectionId' => ID::unique(),
'name' => 'Test Export Collection',
'permissions' => []
]);
$this->assertEquals(201, $collection['headers']['status-code']);
$collectionId = $collection['body']['$id'];
// Create a simple attribute like the basic test
$name = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'name',
'size' => 255,
'required' => true,
]);
$this->assertEquals(202, $name['headers']['status-code']);
// Create a simple attribute like the basic test
$email = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/string', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'key' => 'email',
'size' => 255,
'required' => false,
]);
$this->assertEquals(202, $email['headers']['status-code']);
\sleep(3);
// Create sample documents
for ($i = 1; $i <= 10; $i++) {
$doc = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'documentId' => ID::unique(),
'data' => [
'name' => 'Test User ' . $i,
'email' => 'user' . $i . '@appwrite.io'
]
]);
$this->assertEquals(201, $doc['headers']['status-code'], 'Failed to create document ' . $i);
}
// Verify documents were created
$docs = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(200, $docs['headers']['status-code']);
$this->assertEquals(10, $docs['body']['total'], 'Expected 10 documents but got ' . $docs['body']['total']);
// Perform JSON export with notification enabled (uses internal bucket)
$migration = $this->client->call(Client::METHOD_POST, '/migrations/json/exports', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()), [
'resourceId' => $databaseId . ':' . $collectionId,
'filename' => 'test-json-export',
'columns' => [],
'queries' => [],
'notify' => true
]);
$this->assertEquals(202, $migration['headers']['status-code']);
$this->assertNotEmpty($migration['body']['$id']);
$migrationId = $migration['body']['$id'];
$this->assertEventually(function () use ($migrationId) {
$response = $this->client->call(Client::METHOD_GET, '/migrations/' . $migrationId, [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals('finished', $response['body']['stage']);
$this->assertEquals('completed', $response['body']['status']);
$this->assertEquals('Appwrite', $response['body']['source']);
$this->assertEquals('JSON', $response['body']['destination']);
return true;
}, 30_000, 500);
// Check that email was sent with download link
$lastEmail = $this->getLastEmail();
$this->assertNotEmpty($lastEmail);
$this->assertEquals('Your JSON export is ready', $lastEmail['subject']);
$this->assertStringContainsStringIgnoringCase('Your data export has been completed successfully', $lastEmail['text']);
// Extract download URL from email HTML
\preg_match('/href="([^"]*\/storage\/buckets\/[^"]*\/push[^"]*)"/', $lastEmail['html'], $matches);
$this->assertNotEmpty($matches[1], 'Download URL not found in email');
$downloadUrl = html_entity_decode($matches[1]);
// Parse the URL to extract components
$components = \parse_url($downloadUrl);
$this->assertNotEmpty($components);
\parse_str($components['query'] ?? '', $queryParams);
$this->assertArrayHasKey('jwt', $queryParams, 'JWT not found in download URL');
$this->assertNotEmpty($queryParams['jwt']);
$this->assertArrayHasKey('project', $queryParams, 'Project not found in download URL');
$this->assertStringContainsString('/storage/buckets/default/files/', $downloadUrl);
// Test download with JWT
$path = \str_replace('/v1', '', $components['path']);
$downloadWithJwt = $this->client->call(Client::METHOD_GET, $path . '?project=' . $queryParams['project'] . '&jwt=' . $queryParams['jwt']);
$this->assertEquals(200, $downloadWithJwt['headers']['status-code'], 'Failed to download file with JWT');
// Verify the downloaded content is valid JSON
$jsonData = $downloadWithJwt['body'];
$this->assertNotEmpty($jsonData, 'JSON export should not be empty');
$decoded = json_decode($jsonData, true);
$this->assertIsArray($decoded, 'JSON should be valid and decodable');
$this->assertCount(10, $decoded, 'JSON should contain 10 documents');
$this->assertArrayHasKey('name', $decoded[0], 'JSON documents should contain name field');
$this->assertArrayHasKey('email', $decoded[0], 'JSON documents should contain email field');
$this->assertStringContainsString('Test User', $decoded[0]['name'], 'JSON should contain test data');
// Cleanup
$this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
}
}
@@ -0,0 +1,254 @@
[
{
"$id": "z1y2x3w4v5u6t7s8",
"$createdAt": "2022-10-23T10:33:01+00:00",
"$updatedAt": "2023-03-15T12:00:41+00:00",
"$permissions": [
"read(\"any\")",
"update(\"user:123\")"
],
"name": "Diamond Mendez",
"age": 56
},
{
"$id": "r9q0p1o2n3m4l5k6",
"$createdAt": "2021-08-11T21:05:13+00:00",
"$updatedAt": "2024-01-02T08:45:22+00:00",
"$permissions": [
"read(\"any\")",
"update(\"user:456\")"
],
"name": "Michael Huff",
"age": 20
},
{
"$id": "j7i8h9g0f1e2d3c4",
"$createdAt": "2020-05-29T14:22:56+00:00",
"$updatedAt": "2022-11-30T18:19:33+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Alyssa Rodriguez",
"age": 37
},
{
"$id": "b5a6z7y8x9w0v1u2",
"$createdAt": "2023-01-18T03:44:09+00:00",
"$updatedAt": "2023-09-07T23:50:17+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Barbara Smith",
"age": 26
},
{
"$id": "t3s4r5q6p7o8n9m0",
"$createdAt": "2020-11-02T09:12:45+00:00",
"$updatedAt": "2021-07-21T15:30:55+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Evelyn Edwards",
"age": 54
},
{
"$id": "l1k2j3i4h5g6f7e8",
"$createdAt": "2022-03-19T19:55:27+00:00",
"$updatedAt": "2024-05-14T06:28:11+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Tina Richardson",
"age": 41
},
{
"$id": "d9c0b1a2z3y4x5w6",
"$createdAt": "2021-04-07T01:18:34+00:00",
"$updatedAt": "2023-06-25T11:47:04+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Joel Hernandez",
"age": 49
},
{
"$id": "v7u8t9s0r1q2p3o4",
"$createdAt": "2023-08-22T16:40:18+00:00",
"$updatedAt": "2024-02-19T04:09:58+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Zachary Cooper",
"age": 59
},
{
"$id": "n5m6l7k8j9i0h1g2",
"$createdAt": "2020-02-12T07:59:01+00:00",
"$updatedAt": "2022-09-08T13:21:49+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Brittany Spears",
"age": 20
},
{
"$id": "f3e4d5c6b7a8z9y0",
"$createdAt": "2021-12-05T22:33:12+00:00",
"$updatedAt": "2023-11-11T02:55:37+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Holly White",
"age": 47
},
{
"$id": "x1w2v3u4t5s6r7q8",
"$createdAt": "2022-07-14T05:01:50+00:00",
"$updatedAt": "2024-04-01T20:10:26+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Kimberly Barnes",
"age": 27
},
{
"$id": "p9o0n1m2l3k4j5i6",
"$createdAt": "2020-09-28T11:27:36+00:00",
"$updatedAt": "2021-10-17T09:38:08+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Stephen Miller",
"age": 53
},
{
"$id": "h7g8f9e0d1c2b3a4",
"$createdAt": "2023-04-04T08:15:59+00:00",
"$updatedAt": "2024-06-29T17:03:14+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Yvonne Newman",
"age": 41
},
{
"$id": "y5x6w7v8u9t0s1r2",
"$createdAt": "2021-01-25T18:09:21+00:00",
"$updatedAt": "2022-08-16T22:44:51+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Carol Kane",
"age": 38
},
{
"$id": "q3p4o5n6m7l8k9j0",
"$createdAt": "2022-06-09T12:53:47+00:00",
"$updatedAt": "2023-12-24T01:16:05+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Doris Foster",
"age": 44
},
{
"$id": "i1h2g3f4e5d6c7b8",
"$createdAt": "2020-07-03T23:37:02+00:00",
"$updatedAt": "2021-05-09T05:52:43+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Joseph Stokes",
"age": 28
},
{
"$id": "a9z0y1x2w3v4u5t6",
"$createdAt": "2023-10-10T02:20:15+00:00",
"$updatedAt": "2024-03-28T14:33:29+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Steve Williams",
"age": 31
},
{
"$id": "s7r8q9p0o1n2m3l4",
"$createdAt": "2021-06-16T13:48:53+00:00",
"$updatedAt": "2022-04-22T07:07:19+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "James Carey",
"age": 29
},
{
"$id": "k5j6i7h8g9f0e1d2",
"$createdAt": "2022-12-27T20:06:38+00:00",
"$updatedAt": "2023-08-03T10:25:57+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Kathryn Henry",
"age": 38
},
{
"$id": "c3b4a5z6y7x8w9v0",
"$createdAt": "2020-04-20T04:41:24+00:00",
"$updatedAt": "2021-02-13T19:14:06+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Christopher Landry",
"age": 23
},
{
"$id": "u1t2s3r4q5p6o7n8",
"$createdAt": "2023-05-08T00:58:10+00:00",
"$updatedAt": "2024-07-05T03:36:48+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Jennifer Mcgee",
"age": 62
},
{
"$id": "m9l0k1j2i3h4g5f6",
"$createdAt": "2021-09-01T06:11:42+00:00",
"$updatedAt": "2022-01-26T16:59:23+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Cathy Church",
"age": 35
},
{
"$id": "e7d8c9b0a1z2y3x4",
"$createdAt": "2022-02-18T15:24:07+00:00",
"$updatedAt": "2023-04-12T00:40:31+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Jose Lopez",
"age": 41
},
{
"$id": "w5v6u7t8s9r0q1p2",
"$createdAt": "2020-12-13T09:03:55+00:00",
"$updatedAt": "2021-11-06T11:23:16+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "William Rose",
"age": 30
},
{
"$id": "o3n4m5l6k7j8i9h0",
"$createdAt": "2021-12-13T09:03:55+00:00",
"$updatedAt": "2022-11-06T11:23:16+00:00",
"$permissions": [
"read(\"any\")"
],
"name": "Charles Hammer",
"age": 61
}
]
+502
View File
@@ -0,0 +1,502 @@
[
{
"$id": "hxfcwpcas5xokpwe",
"name": "Diamond Mendez",
"age": 56
},
{
"$id": "gw8nxwf6esn3tfwf",
"name": "Michael Huff",
"age": 20
},
{
"$id": "xb6bxg56lral1qy9",
"name": "Alyssa Rodriguez",
"age": 37
},
{
"$id": "imerjq5j36y3agh2",
"name": "Barbara Smith",
"age": 26
},
{
"$id": "07yq9qdlhmbzmr35",
"name": "Evelyn Edwards",
"age": 54
},
{
"$id": "ksqo631sbhwj5ltg",
"name": "Tina Richardson",
"age": 41
},
{
"$id": "j7zlndgu0gbshp15",
"name": "Joel Hernandez",
"age": 49
},
{
"$id": "mfntvnljrcmf7h6v",
"name": "Zachary Cooper",
"age": 59
},
{
"$id": "5f9b01nziqu2h8ed",
"name": "Brittany Spears",
"age": 20
},
{
"$id": "4vxzbnzraqznk5u8",
"name": "Holly White",
"age": 47
},
{
"$id": "d4ywy3mtphaatbpf",
"name": "Kimberly Barnes",
"age": 27
},
{
"$id": "88odnk6nthyyvbal",
"name": "Stephen Miller",
"age": 53
},
{
"$id": "08oekee3fn7mzaa5",
"name": "Yvonne Newman",
"age": 41
},
{
"$id": "quw55kn9895i5e4v",
"name": "Carol Kane",
"age": 38
},
{
"$id": "nge6bm8ykripei6f",
"name": "Doris Foster",
"age": 44
},
{
"$id": "4k16i33s0xl2ypx9",
"name": "Joseph Stokes",
"age": 28
},
{
"$id": "q0j5rxbgid66snyf",
"name": "Steve Williams",
"age": 31
},
{
"$id": "n1oxun7mqq3p103y",
"name": "James Carey",
"age": 29
},
{
"$id": "0dbvs840jkf8i0ye",
"name": "Kathryn Henry",
"age": 38
},
{
"$id": "5sfaidgs1h87v15v",
"name": "Christopher Landry",
"age": 23
},
{
"$id": "vg3punvfu5khmf41",
"name": "Jennifer Mcgee",
"age": 62
},
{
"$id": "f933qydr9u5b2r11",
"name": "Cathy Church",
"age": 35
},
{
"$id": "wjv87y1inf8yk32s",
"name": "Jose Lopez",
"age": 41
},
{
"$id": "uljysdvdlcyrbrwk",
"name": "William Rose",
"age": 30
},
{
"$id": "ot8xtzh77j55wq0s",
"name": "Sarah Ford",
"age": 26
},
{
"$id": "9t76vnsv2u36s43t",
"name": "Alisha Jones",
"age": 61
},
{
"$id": "66y4tnty62hw8c02",
"name": "Kristin Kelly",
"age": 61
},
{
"$id": "2punfblazi5v16ar",
"name": "Brendan Stout",
"age": 40
},
{
"$id": "sxhr4nf5w2gx4wbg",
"name": "Kelly Cruz",
"age": 18
},
{
"$id": "68dvrqfwqnkq5el9",
"name": "Samantha Martin",
"age": 50
},
{
"$id": "20192l6dbeinhkh0",
"name": "David Santos",
"age": 46
},
{
"$id": "si0l4dgay09ebfmf",
"name": "Elizabeth Carroll",
"age": 22
},
{
"$id": "lhse40vbldqb6ap1",
"name": "Corey Owens",
"age": 46
},
{
"$id": "h5t3pslykyx3kxfm",
"name": "Shelby Mueller",
"age": 65
},
{
"$id": "ldc0luydrw6jub0f",
"name": "Dr. Sylvia Myers",
"age": 29
},
{
"$id": "voc9628xg4dsgw2y",
"name": "Scott Freeman",
"age": 48
},
{
"$id": "o4y0gk3gqv1ax2fz",
"name": "Christopher Atkinson",
"age": 21
},
{
"$id": "u1n3x4e4u7e0vzj6",
"name": "Sean Diaz",
"age": 31
},
{
"$id": "s36eskwtm0w7lwr7",
"name": "Bobby Dyer",
"age": 57
},
{
"$id": "4hjnag1p5iwvtixd",
"name": "Daniel Hall",
"age": 62
},
{
"$id": "m91d80oxsa216zbh",
"name": "Jennifer Ramirez",
"age": 65
},
{
"$id": "5hj6858zo2g85n6v",
"name": "Angela Jackson",
"age": 57
},
{
"$id": "8m8oihv9a1e7nn92",
"name": "Kelly Lewis",
"age": 36
},
{
"$id": "7azy39la0no0mxi7",
"name": "Jessica Munoz",
"age": 55
},
{
"$id": "47pmjkhnnqhyit8c",
"name": "Kelly George",
"age": 65
},
{
"$id": "6j6cpy4kgneg1mmh",
"name": "Anthony Johnson",
"age": 65
},
{
"$id": "tnlmtvap1zz89km9",
"name": "Regina Fields",
"age": 61
},
{
"$id": "6cyuvnwwqdmrpfzh",
"name": "Sharon Schaefer",
"age": 30
},
{
"$id": "p1v4pyu2pqodc0ey",
"name": "Jacob French",
"age": 62
},
{
"$id": "6npynnhjt2jd05xo",
"name": "Jessica Costa",
"age": 23
},
{
"$id": "wcxedf13n2e9qi4l",
"name": "George Hardy",
"age": 53
},
{
"$id": "yf2xlcmszk2tqeig",
"name": "Andrea Allison",
"age": 20
},
{
"$id": "3bf2zzv7poststwa",
"name": "Kevin Ferguson",
"age": 32
},
{
"$id": "c2iataz0hhv39q63",
"name": "Joseph Johnson",
"age": 58
},
{
"$id": "3e8npxhov4a39pvq",
"name": "Ashley Martinez",
"age": 18
},
{
"$id": "t7dp41tysipytywq",
"name": "Charles Nixon",
"age": 23
},
{
"$id": "z8cztq7c47phyfhk",
"name": "Carol Dudley",
"age": 40
},
{
"$id": "2636f9d8r4ipm3h6",
"name": "David Weber",
"age": 51
},
{
"$id": "eh3f6wxtvkjq6ykq",
"name": "Scott Robinson",
"age": 32
},
{
"$id": "raskbwpsje69a59h",
"name": "Anthony Hardy",
"age": 38
},
{
"$id": "90hn1p0b4cs9e2og",
"name": "Mackenzie Owens",
"age": 52
},
{
"$id": "am3swwfbo076x0v1",
"name": "Brian Foster",
"age": 27
},
{
"$id": "5uw7utb9lq5cfncw",
"name": "Hannah Forbes",
"age": 56
},
{
"$id": "cs6mbfzkzifefx6r",
"name": "Lauren Reed",
"age": 26
},
{
"$id": "ftw3uvztziiz9x00",
"name": "Morgan Smith",
"age": 28
},
{
"$id": "uhrqseeo43mozpaq",
"name": "Samantha Alexander",
"age": 65
},
{
"$id": "pvvmzyfc1lxor11e",
"name": "Tiffany Roberts",
"age": 20
},
{
"$id": "jia7bdag4abz123s",
"name": "Emily Hayes",
"age": 34
},
{
"$id": "h6oozcngbz8o5x4y",
"name": "Rebecca Villegas",
"age": 52
},
{
"$id": "9v6z1pn2f9twcy12",
"name": "Donald Shah",
"age": 61
},
{
"$id": "wzz3jduioso77o7f",
"name": "Denise Cain",
"age": 59
},
{
"$id": "u51plhgvjodkswnr",
"name": "Kristine Ramirez",
"age": 53
},
{
"$id": "t1uhkmiytfyc13vc",
"name": "Stacey Adkins",
"age": 61
},
{
"$id": "iqaqnf0ybg2ct507",
"name": "Daniel Hunt",
"age": 20
},
{
"$id": "idwrwv2uu4hcpv2i",
"name": "Roberta Johnson",
"age": 48
},
{
"$id": "2yd2hd6auetjacyo",
"name": "Jason Williamson",
"age": 39
},
{
"$id": "egrmdbibnjhi914x",
"name": "Sandra Robinson",
"age": 50
},
{
"$id": "15m1pz2bb0ercgyk",
"name": "Steve Rice",
"age": 25
},
{
"$id": "0i21bhkxdagjurb7",
"name": "Kimberly Fritz",
"age": 53
},
{
"$id": "726ofi7h5snreq67",
"name": "Brianna Reynolds",
"age": 33
},
{
"$id": "csqxse3wym56eim6",
"name": "Alexander Williams",
"age": 50
},
{
"$id": "qeaoylnrsf8p3byg",
"name": "Andrew Thomas",
"age": 25
},
{
"$id": "edsswobumzyzbvhf",
"name": "Austin Williams",
"age": 57
},
{
"$id": "hdzhzpt0ahy5hkib",
"name": "Nicholas Williams",
"age": 24
},
{
"$id": "w1qmvmg4roa8xnwu",
"name": "Mrs. Michelle Cisneros",
"age": 48
},
{
"$id": "3z3o73x7adyuo6w0",
"name": "Stacey Smith",
"age": 39
},
{
"$id": "sse2u5zlgoqrgmcf",
"name": "Laura Beck",
"age": 20
},
{
"$id": "rvovijmvch58r4yx",
"name": "Molly Clark",
"age": 51
},
{
"$id": "doe06nrx8sg5mcuv",
"name": "Carmen Morris",
"age": 41
},
{
"$id": "jbjdwuvj5s4kw04y",
"name": "Amanda Munoz",
"age": 20
},
{
"$id": "6k2ewkla7js0yw23",
"name": "Rachel Collins",
"age": 44
},
{
"$id": "fcxuyr4kkhrnigu1",
"name": "John Alexander",
"age": 18
},
{
"$id": "d25fuwlos5mk07o0",
"name": "Stacy Hunter",
"age": 22
},
{
"$id": "1vdai2rxmwd57oet",
"name": "Eric Massey",
"age": 40
},
{
"$id": "pq4jnt9izu1wlrzd",
"name": "Scott Garcia",
"age": 20
},
{
"$id": "lz9kfc0lty5xcz14",
"name": "Cassandra Nelson",
"age": 35
},
{
"$id": "pu7w6tyab5jd4we9",
"name": "Aaron Johnson",
"age": 50
},
{
"$id": "8dupswd2kqwdyn8v",
"name": "Shannon Sherman",
"age": 45
},
{
"$id": "ye466l71jthiz2p6",
"name": "April Garcia",
"age": 60
},
{
"$id": "xogsmfwb73l16qdt",
"name": "Evan Lynn",
"age": 20
}
]
+602
View File
@@ -0,0 +1,602 @@
[
{
"$id": "r5ctmrqwqn1m3rc0",
"name": "Diamond Mendez",
"age": 56,
"email": "diamond.mendez@example.com"
},
{
"$id": "wxwp7e7q7nx3ltfx",
"name": "Michael Huff",
"age": 20,
"email": "michael.huff@example.com"
},
{
"$id": "4ct0b38fwaojawlv",
"name": "Alyssa Rodriguez",
"age": 37,
"email": "alyssa.rodriguez@example.com"
},
{
"$id": "o0jjcuygbta2zvga",
"name": "Barbara Smith",
"age": 26,
"email": "barbara.smith@example.com"
},
{
"$id": "bdy6l2ofl8klb4pb",
"name": "Evelyn Edwards",
"age": 54,
"email": "evelyn.edwards@example.com"
},
{
"$id": "rkccl72v7zwtbila",
"name": "Tina Richardson",
"age": 41,
"email": "tina.richardson@example.com"
},
{
"$id": "cilw7um0cd927esj",
"name": "Joel Hernandez",
"age": 49,
"email": "joel.hernandez@example.com"
},
{
"$id": "60povvz0votkve1j",
"name": "Zachary Cooper",
"age": 59,
"email": "zachary.cooper@example.com"
},
{
"$id": "ayow5dzwktvbbtp2",
"name": "Brittany Spears",
"age": 20,
"email": "brittany.spears@example.com"
},
{
"$id": "cfru98od0lab0b2n",
"name": "Holly White",
"age": 47,
"email": "holly.white@example.com"
},
{
"$id": "vjxjldvu3r6uylq6",
"name": "Kimberly Barnes",
"age": 27,
"email": "kimberly.barnes@example.com"
},
{
"$id": "d1p47hl97pw6xowb",
"name": "Stephen Miller",
"age": 53,
"email": "stephen.miller@example.com"
},
{
"$id": "yxk6qaa5ryb3gqrb",
"name": "Yvonne Newman",
"age": 41,
"email": "yvonne.newman@example.com"
},
{
"$id": "ifkeo7j8t7hfd7z8",
"name": "Carol Kane",
"age": 38,
"email": "carol.kane@example.com"
},
{
"$id": "e1q4lq8vvpxp9ysb",
"name": "Doris Foster",
"age": 44,
"email": "doris.foster@example.com"
},
{
"$id": "obec6d52dc6swzsf",
"name": "Joseph Stokes",
"age": 28,
"email": "joseph.stokes@example.com"
},
{
"$id": "26v06la6ug8wkvim",
"name": "Steve Williams",
"age": 31,
"email": "steve.williams@example.com"
},
{
"$id": "m4glre4ch12vkxp6",
"name": "James Carey",
"age": 29,
"email": "james.carey@example.com"
},
{
"$id": "jee8fyfffnjugsd5",
"name": "Kathryn Henry",
"age": 38,
"email": "kathryn.henry@example.com"
},
{
"$id": "miquc6ljb9l3a31r",
"name": "Christopher Landry",
"age": 23,
"email": "christopher.landry@example.com"
},
{
"$id": "ghf7da7seeuj1zdl",
"name": "Jennifer Mcgee",
"age": 62,
"email": "jennifer.mcgee@example.com"
},
{
"$id": "x7h11phjrz77w0q8",
"name": "Cathy Church",
"age": 35,
"email": "cathy.church@example.com"
},
{
"$id": "dn8u5lsux4708z6j",
"name": "Jose Lopez",
"age": 41,
"email": "jose.lopez@example.com"
},
{
"$id": "zb7fdlyohuyy5i9k",
"name": "William Rose",
"age": 30,
"email": "william.rose@example.com"
},
{
"$id": "qyrj8m9krp4dt4wt",
"name": "Sarah Ford",
"age": 26,
"email": "sarah.ford@example.com"
},
{
"$id": "t6t673zpfyhhz8pg",
"name": "Alisha Jones",
"age": 61,
"email": "alisha.jones@example.com"
},
{
"$id": "0hfbo0iy1q9bwc2n",
"name": "Kristin Kelly",
"age": 61,
"email": "kristin.kelly@example.com"
},
{
"$id": "8alv4e4xrpcj443z",
"name": "Brendan Stout",
"age": 40,
"email": "brendan.stout@example.com"
},
{
"$id": "qxm7a0z32xdkzxdj",
"name": "Kelly Cruz",
"age": 18,
"email": "kelly.cruz@example.com"
},
{
"$id": "885mti7j7oiz5p5g",
"name": "Samantha Martin",
"age": 50,
"email": "samantha.martin@example.com"
},
{
"$id": "v8i7dvhby6711m66",
"name": "David Santos",
"age": 46,
"email": "david.santos@example.com"
},
{
"$id": "rggc0ow8ccd2jgvp",
"name": "Elizabeth Carroll",
"age": 22,
"email": "elizabeth.carroll@example.com"
},
{
"$id": "012472s64rvzq1c4",
"name": "Corey Owens",
"age": 46,
"email": "corey.owens@example.com"
},
{
"$id": "0k2xrwj4g33ut14y",
"name": "Shelby Mueller",
"age": 65,
"email": "shelby.mueller@example.com"
},
{
"$id": "s3y9rl4uzf3difiq",
"name": "Dr. Sylvia Myers",
"age": 29,
"email": "sylvia.myers@example.com"
},
{
"$id": "ntpc2td892t7f6an",
"name": "Scott Freeman",
"age": 48,
"email": "scott.freeman@example.com"
},
{
"$id": "7f703gibyr5ijdmt",
"name": "Christopher Atkinson",
"age": 21,
"email": "christopher.atkinson@example.com"
},
{
"$id": "r2jdf2pivkxmqd0l",
"name": "Sean Diaz",
"age": 31,
"email": "sean.diaz@example.com"
},
{
"$id": "fj98fji1lrxeigs9",
"name": "Bobby Dyer",
"age": 57,
"email": "bobby.dyer@example.com"
},
{
"$id": "mehqmzp9u7xv1z3j",
"name": "Daniel Hall",
"age": 62,
"email": "daniel.hall@example.com"
},
{
"$id": "4cd5ln65qjfv3h4j",
"name": "Jennifer Ramirez",
"age": 65,
"email": "jennifer.ramirez@example.com"
},
{
"$id": "wdi6ap0oa7m1ab1d",
"name": "Angela Jackson",
"age": 57,
"email": "angela.jackson@example.com"
},
{
"$id": "l2foqjhxvjhjzijb",
"name": "Kelly Lewis",
"age": 36,
"email": "kelly.lewis@example.com"
},
{
"$id": "d963t5yu35uagwm4",
"name": "Jessica Munoz",
"age": 55,
"email": "jessica.munoz@example.com"
},
{
"$id": "99ez9uxsim8zp64m",
"name": "Kelly George",
"age": 65,
"email": "kelly.george@example.com"
},
{
"$id": "v7wl221gycftl63d",
"name": "Anthony Johnson",
"age": 65,
"email": "anthony.johnson@example.com"
},
{
"$id": "p2zzj0lnmjvqzfc3",
"name": "Regina Fields",
"age": 61,
"email": "regina.fields@example.com"
},
{
"$id": "fk655e243z2ivvx6",
"name": "Sharon Schaefer",
"age": 30,
"email": "sharon.schaefer@example.com"
},
{
"$id": "4ywsv6fw8g2d8ncw",
"name": "Jacob French",
"age": 62,
"email": "jacob.french@example.com"
},
{
"$id": "y61q9k6g4h0fxxz4",
"name": "Jessica Costa",
"age": 23,
"email": "jessica.costa@example.com"
},
{
"$id": "knj4hfzsthk7vx5n",
"name": "George Hardy",
"age": 53,
"email": "george.hardy@example.com"
},
{
"$id": "a88u9w2pct2nn8l6",
"name": "Andrea Allison",
"age": 20,
"email": "andrea.allison@example.com"
},
{
"$id": "hw960v1ybycrwr5o",
"name": "Kevin Ferguson",
"age": 32,
"email": "kevin.ferguson@example.com"
},
{
"$id": "j9garslpgx6jgzgb",
"name": "Joseph Johnson",
"age": 58,
"email": "joseph.johnson@example.com"
},
{
"$id": "gv101bz36elm84cd",
"name": "Ashley Martinez",
"age": 18,
"email": "ashley.martinez@example.com"
},
{
"$id": "xrvzgt3gc0c7g4cl",
"name": "Charles Nixon",
"age": 23,
"email": "charles.nixon@example.com"
},
{
"$id": "awjlu7uk0eutcfpb",
"name": "Carol Dudley",
"age": 40,
"email": "carol.dudley@example.com"
},
{
"$id": "95oi26p2zdudpime",
"name": "David Weber",
"age": 51,
"email": "david.weber@example.com"
},
{
"$id": "h8x7pkhdvu5bcp89",
"name": "Scott Robinson",
"age": 32,
"email": "scott.robinson@example.com"
},
{
"$id": "oj6cu4jm1z2afe7s",
"name": "Anthony Hardy",
"age": 38,
"email": "anthony.hardy@example.com"
},
{
"$id": "hgsdi1g30poqqmf0",
"name": "Mackenzie Owens",
"age": 52,
"email": "mackenzie.owens@example.com"
},
{
"$id": "8fzdz914bqlqk2tc",
"name": "Brian Foster",
"age": 27,
"email": "brian.foster@example.com"
},
{
"$id": "fwlqoeiunjhczpl0",
"name": "Hannah Forbes",
"age": 56,
"email": "hannah.forbes@example.com"
},
{
"$id": "rsv8156goe8z4j6j",
"name": "Lauren Reed",
"age": 26,
"email": "lauren.reed@example.com"
},
{
"$id": "1fjqv3w7uwbswe2p",
"name": "Morgan Smith",
"age": 28,
"email": "morgan.smith@example.com"
},
{
"$id": "soqrzmhhg05hhzn4",
"name": "Samantha Alexander",
"age": 65,
"email": "samantha.alexander@example.com"
},
{
"$id": "8quy52cto9kjjokp",
"name": "Tiffany Roberts",
"age": 20,
"email": "tiffany.roberts@example.com"
},
{
"$id": "e3i1g1lw04v7jd89",
"name": "Emily Hayes",
"age": 34,
"email": "emily.hayes@example.com"
},
{
"$id": "s7n8lzb0sw7h93z1",
"name": "Rebecca Villegas",
"age": 52,
"email": "rebecca.villegas@example.com"
},
{
"$id": "e2lc7i81tpkqs1rp",
"name": "Donald Shah",
"age": 61,
"email": "donald.shah@example.com"
},
{
"$id": "3oe2mysup1xluiw0",
"name": "Denise Cain",
"age": 59,
"email": "denise.cain@example.com"
},
{
"$id": "1vqypc37f85nuqz4",
"name": "Kristine Ramirez",
"age": 53,
"email": "kristine.ramirez@example.com"
},
{
"$id": "m0uh7r3dc6z8ucb4",
"name": "Stacey Adkins",
"age": 61,
"email": "stacey.adkins@example.com"
},
{
"$id": "jdofz6x1ahganmqf",
"name": "Daniel Hunt",
"age": 20,
"email": "daniel.hunt@example.com"
},
{
"$id": "vbe903c2q4m4q97g",
"name": "Roberta Johnson",
"age": 48,
"email": "roberta.johnson@example.com"
},
{
"$id": "sndngrxuwpd93pdb",
"name": "Jason Williamson",
"age": 39,
"email": "jason.williamson@example.com"
},
{
"$id": "66hvaw2p5xwf07p8",
"name": "Sandra Robinson",
"age": 50,
"email": "sandra.robinson@example.com"
},
{
"$id": "9pvingfsl8cmag5c",
"name": "Steve Rice",
"age": 25,
"email": "steve.rice@example.com"
},
{
"$id": "qe154m5hh00u4iiz",
"name": "Kimberly Fritz",
"age": 53,
"email": "kimberly.fritz@example.com"
},
{
"$id": "avqnbrco2f0tfupk",
"name": "Brianna Reynolds",
"age": 33,
"email": "brianna.reynolds@example.com"
},
{
"$id": "cqs10gi2qu1r3ugb",
"name": "Alexander Williams",
"age": 50,
"email": "alexander.williams@example.com"
},
{
"$id": "jrpmfi6hmm7pmegp",
"name": "Andrew Thomas",
"age": 25,
"email": "andrew.thomas@example.com"
},
{
"$id": "heeab2qqf0zm446f",
"name": "Austin Williams",
"age": 57,
"email": "austin.williams@example.com"
},
{
"$id": "bkhugvnil7kjchm6",
"name": "Nicholas Williams",
"age": 24,
"email": "nicholas.williams@example.com"
},
{
"$id": "b045j302pvv8l1p4",
"name": "Mrs. Michelle Cisneros",
"age": 48,
"email": "michelle.cisneros@example.com"
},
{
"$id": "aikhii5q210lrfpr",
"name": "Stacey Smith",
"age": 39,
"email": "stacey.smith@example.com"
},
{
"$id": "x0zajitea1z2dfo0",
"name": "Laura Beck",
"age": 20,
"email": "laura.beck@example.com"
},
{
"$id": "abeecki7mdff1tv0",
"name": "Molly Clark",
"age": 51,
"email": "molly.clark@example.com"
},
{
"$id": "yizama8r3i1to548",
"name": "Carmen Morris",
"age": 41,
"email": "carmen.morris@example.com"
},
{
"$id": "8690yh971g4rgspj",
"name": "Amanda Munoz",
"age": 20,
"email": "amanda.munoz@example.com"
},
{
"$id": "cd9vk5v97t359ul2",
"name": "Rachel Collins",
"age": 44,
"email": "rachel.collins@example.com"
},
{
"$id": "wrkgmx1v0w9ja4l8",
"name": "John Alexander",
"age": 18,
"email": "john.alexander@example.com"
},
{
"$id": "kxp3ucqo6ped4ss7",
"name": "Stacy Hunter",
"age": 22,
"email": "stacy.hunter@example.com"
},
{
"$id": "dbvv8okae2qgo0gm",
"name": "Eric Massey",
"age": 40,
"email": "eric.massey@example.com"
},
{
"$id": "9tn3nm6ppnayisje",
"name": "Scott Garcia",
"age": 20,
"email": "scott.garcia@example.com"
},
{
"$id": "1xuc5t60xpcvd4qi",
"name": "Cassandra Nelson",
"age": 35,
"email": "cassandra.nelson@example.com"
},
{
"$id": "qao1nulwn0kqyfkc",
"name": "Aaron Johnson",
"age": 50,
"email": "aaron.johnson@example.com"
},
{
"$id": "kd2q6owvuwsy5knx",
"name": "Shannon Sherman",
"age": 45,
"email": "shannon.sherman@example.com"
},
{
"$id": "wsl37kjo0bib4wrc",
"name": "April Garcia",
"age": 60,
"email": "april.garcia@example.com"
},
{
"$id": "ujlz7k84xzfx4khs",
"name": "Evan Lynn",
"age": 20,
"email": "evan.lynn@example.com"
}
]
+402
View File
@@ -0,0 +1,402 @@
[
{
"$id": "hxfcwpcas5xokpwe",
"name": "Diamond Mendez"
},
{
"$id": "gw8nxwf6esn3tfwf",
"name": "Michael Huff"
},
{
"$id": "xb6bxg56lral1qy9",
"name": "Alyssa Rodriguez"
},
{
"$id": "imerjq5j36y3agh2",
"name": "Barbara Smith"
},
{
"$id": "07yq9qdlhmbzmr35",
"name": "Evelyn Edwards"
},
{
"$id": "ksqo631sbhwj5ltg",
"name": "Tina Richardson"
},
{
"$id": "j7zlndgu0gbshp15",
"name": "Joel Hernandez"
},
{
"$id": "mfntvnljrcmf7h6v",
"name": "Zachary Cooper"
},
{
"$id": "5f9b01nziqu2h8ed",
"name": "Brittany Spears"
},
{
"$id": "4vxzbnzraqznk5u8",
"name": "Holly White"
},
{
"$id": "d4ywy3mtphaatbpf",
"name": "Kimberly Barnes"
},
{
"$id": "88odnk6nthyyvbal",
"name": "Stephen Miller"
},
{
"$id": "08oekee3fn7mzaa5",
"name": "Yvonne Newman"
},
{
"$id": "quw55kn9895i5e4v",
"name": "Carol Kane"
},
{
"$id": "nge6bm8ykripei6f",
"name": "Doris Foster"
},
{
"$id": "4k16i33s0xl2ypx9",
"name": "Joseph Stokes"
},
{
"$id": "q0j5rxbgid66snyf",
"name": "Steve Williams"
},
{
"$id": "n1oxun7mqq3p103y",
"name": "James Carey"
},
{
"$id": "0dbvs840jkf8i0ye",
"name": "Kathryn Henry"
},
{
"$id": "5sfaidgs1h87v15v",
"name": "Christopher Landry"
},
{
"$id": "vg3punvfu5khmf41",
"name": "Jennifer Mcgee"
},
{
"$id": "f933qydr9u5b2r11",
"name": "Cathy Church"
},
{
"$id": "wjv87y1inf8yk32s",
"name": "Jose Lopez"
},
{
"$id": "uljysdvdlcyrbrwk",
"name": "William Rose"
},
{
"$id": "ot8xtzh77j55wq0s",
"name": "Sarah Ford"
},
{
"$id": "9t76vnsv2u36s43t",
"name": "Alisha Jones"
},
{
"$id": "66y4tnty62hw8c02",
"name": "Kristin Kelly"
},
{
"$id": "2punfblazi5v16ar",
"name": "Brendan Stout"
},
{
"$id": "sxhr4nf5w2gx4wbg",
"name": "Kelly Cruz"
},
{
"$id": "68dvrqfwqnkq5el9",
"name": "Samantha Martin"
},
{
"$id": "20192l6dbeinhkh0",
"name": "David Santos"
},
{
"$id": "si0l4dgay09ebfmf",
"name": "Elizabeth Carroll"
},
{
"$id": "lhse40vbldqb6ap1",
"name": "Corey Owens"
},
{
"$id": "h5t3pslykyx3kxfm",
"name": "Shelby Mueller"
},
{
"$id": "ldc0luydrw6jub0f",
"name": "Dr. Sylvia Myers"
},
{
"$id": "voc9628xg4dsgw2y",
"name": "Scott Freeman"
},
{
"$id": "o4y0gk3gqv1ax2fz",
"name": "Christopher Atkinson"
},
{
"$id": "u1n3x4e4u7e0vzj6",
"name": "Sean Diaz"
},
{
"$id": "s36eskwtm0w7lwr7",
"name": "Bobby Dyer"
},
{
"$id": "4hjnag1p5iwvtixd",
"name": "Daniel Hall"
},
{
"$id": "m91d80oxsa216zbh",
"name": "Jennifer Ramirez"
},
{
"$id": "5hj6858zo2g85n6v",
"name": "Angela Jackson"
},
{
"$id": "8m8oihv9a1e7nn92",
"name": "Kelly Lewis"
},
{
"$id": "7azy39la0no0mxi7",
"name": "Jessica Munoz"
},
{
"$id": "47pmjkhnnqhyit8c",
"name": "Kelly George"
},
{
"$id": "6j6cpy4kgneg1mmh",
"name": "Anthony Johnson"
},
{
"$id": "tnlmtvap1zz89km9",
"name": "Regina Fields"
},
{
"$id": "6cyuvnwwqdmrpfzh",
"name": "Sharon Schaefer"
},
{
"$id": "p1v4pyu2pqodc0ey",
"name": "Jacob French"
},
{
"$id": "6npynnhjt2jd05xo",
"name": "Jessica Costa"
},
{
"$id": "wcxedf13n2e9qi4l",
"name": "George Hardy"
},
{
"$id": "yf2xlcmszk2tqeig",
"name": "Andrea Allison"
},
{
"$id": "3bf2zzv7poststwa",
"name": "Kevin Ferguson"
},
{
"$id": "c2iataz0hhv39q63",
"name": "Joseph Johnson"
},
{
"$id": "3e8npxhov4a39pvq",
"name": "Ashley Martinez"
},
{
"$id": "t7dp41tysipytywq",
"name": "Charles Nixon"
},
{
"$id": "z8cztq7c47phyfhk",
"name": "Carol Dudley"
},
{
"$id": "2636f9d8r4ipm3h6",
"name": "David Weber"
},
{
"$id": "eh3f6wxtvkjq6ykq",
"name": "Scott Robinson"
},
{
"$id": "raskbwpsje69a59h",
"name": "Anthony Hardy"
},
{
"$id": "90hn1p0b4cs9e2og",
"name": "Mackenzie Owens"
},
{
"$id": "am3swwfbo076x0v1",
"name": "Brian Foster"
},
{
"$id": "5uw7utb9lq5cfncw",
"name": "Hannah Forbes"
},
{
"$id": "cs6mbfzkzifefx6r",
"name": "Lauren Reed"
},
{
"$id": "ftw3uvztziiz9x00",
"name": "Morgan Smith"
},
{
"$id": "uhrqseeo43mozpaq",
"name": "Samantha Alexander"
},
{
"$id": "pvvmzyfc1lxor11e",
"name": "Tiffany Roberts"
},
{
"$id": "jia7bdag4abz123s",
"name": "Emily Hayes"
},
{
"$id": "h6oozcngbz8o5x4y",
"name": "Rebecca Villegas"
},
{
"$id": "9v6z1pn2f9twcy12",
"name": "Donald Shah"
},
{
"$id": "wzz3jduioso77o7f",
"name": "Denise Cain"
},
{
"$id": "u51plhgvjodkswnr",
"name": "Kristine Ramirez"
},
{
"$id": "t1uhkmiytfyc13vc",
"name": "Stacey Adkins"
},
{
"$id": "iqaqnf0ybg2ct507",
"name": "Daniel Hunt"
},
{
"$id": "idwrwv2uu4hcpv2i",
"name": "Roberta Johnson"
},
{
"$id": "2yd2hd6auetjacyo",
"name": "Jason Williamson"
},
{
"$id": "egrmdbibnjhi914x",
"name": "Sandra Robinson"
},
{
"$id": "15m1pz2bb0ercgyk",
"name": "Steve Rice"
},
{
"$id": "0i21bhkxdagjurb7",
"name": "Kimberly Fritz"
},
{
"$id": "726ofi7h5snreq67",
"name": "Brianna Reynolds"
},
{
"$id": "csqxse3wym56eim6",
"name": "Alexander Williams"
},
{
"$id": "qeaoylnrsf8p3byg",
"name": "Andrew Thomas"
},
{
"$id": "edsswobumzyzbvhf",
"name": "Austin Williams"
},
{
"$id": "hdzhzpt0ahy5hkib",
"name": "Nicholas Williams"
},
{
"$id": "w1qmvmg4roa8xnwu",
"name": "Mrs. Michelle Cisneros"
},
{
"$id": "3z3o73x7adyuo6w0",
"name": "Stacey Smith"
},
{
"$id": "sse2u5zlgoqrgmcf",
"name": "Laura Beck"
},
{
"$id": "rvovijmvch58r4yx",
"name": "Molly Clark"
},
{
"$id": "doe06nrx8sg5mcuv",
"name": "Carmen Morris"
},
{
"$id": "jbjdwuvj5s4kw04y",
"name": "Amanda Munoz"
},
{
"$id": "6k2ewkla7js0yw23",
"name": "Rachel Collins"
},
{
"$id": "fcxuyr4kkhrnigu1",
"name": "John Alexander"
},
{
"$id": "d25fuwlos5mk07o0",
"name": "Stacy Hunter"
},
{
"$id": "1vdai2rxmwd57oet",
"name": "Eric Massey"
},
{
"$id": "pq4jnt9izu1wlrzd",
"name": "Scott Garcia"
},
{
"$id": "lz9kfc0lty5xcz14",
"name": "Cassandra Nelson"
},
{
"$id": "pu7w6tyab5jd4we9",
"name": "Aaron Johnson"
},
{
"$id": "8dupswd2kqwdyn8v",
"name": "Shannon Sherman"
},
{
"$id": "ye466l71jthiz2p6",
"name": "April Garcia"
},
{
"$id": "xogsmfwb73l16qdt",
"name": "Evan Lynn"
}
]