diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml
deleted file mode 100644
index 63631f7..0000000
--- a/.github/ISSUE_TEMPLATE/bug.yaml
+++ /dev/null
@@ -1,82 +0,0 @@
-name: "🐛 Bug Report"
-description: "Submit a bug report to help us improve"
-title: "🐛 Bug Report: "
-labels: [bug]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for taking the time to fill out our bug report form 🙏
- - type: textarea
- id: steps-to-reproduce
- validations:
- required: true
- attributes:
- label: "👟 Reproduction steps"
- description: "How do you trigger this bug? Please walk us through it step by step."
- placeholder: "When I ..."
- - type: textarea
- id: expected-behavior
- validations:
- required: true
- attributes:
- label: "👍 Expected behavior"
- description: "What did you think would happen?"
- placeholder: "It should ..."
- - type: textarea
- id: actual-behavior
- validations:
- required: true
- attributes:
- label: "👎 Actual Behavior"
- description: "What did actually happen? Add screenshots, if applicable."
- placeholder: "It actually ..."
- - type: dropdown
- id: appwrite-version
- attributes:
- label: "🎲 Appwrite version"
- description: "What version of Appwrite are you running?"
- options:
- - Version 0.10.x
- - Version 0.9.x
- - Version 0.8.x
- - Version 0.7.x
- - Version 0.6.x
- - Different version (specify in environment)
- validations:
- required: true
- - type: dropdown
- id: operating-system
- attributes:
- label: "💻 Operating system"
- description: "What OS is your server / device running on?"
- options:
- - Linux
- - MacOS
- - Windows
- - Something else
- validations:
- required: true
- - type: textarea
- id: enviromnemt
- validations:
- required: false
- attributes:
- label: "🧱 Your Environment"
- description: "Is your environment customized in any way?"
- placeholder: "I use Cloudflare for ..."
- - type: checkboxes
- id: no-duplicate-issues
- attributes:
- label: "👀 Have you spent some time to check if this issue has been raised before?"
- description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
- options:
- - label: "I checked and didn't find similar issue"
- required: true
- - type: checkboxes
- id: read-code-of-conduct
- attributes:
- label: "🏢 Have you read the Code of Conduct?"
- options:
- - label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
- required: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/documentation.yaml b/.github/ISSUE_TEMPLATE/documentation.yaml
deleted file mode 100644
index 6561dfc..0000000
--- a/.github/ISSUE_TEMPLATE/documentation.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: "📚 Documentation"
-description: "Report an issue related to documentation"
-title: "📚 Documentation: "
-labels: [documentation]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for taking the time to make our documentation better 🙏
- - type: textarea
- id: issue-description
- validations:
- required: true
- attributes:
- label: "💭 Description"
- description: "A clear and concise description of what the issue is."
- placeholder: "Documentation should not ..."
- - type: checkboxes
- id: no-duplicate-issues
- attributes:
- label: "👀 Have you spent some time to check if this issue has been raised before?"
- description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
- options:
- - label: "I checked and didn't find similar issue"
- required: true
- - type: checkboxes
- id: read-code-of-conduct
- attributes:
- label: "🏢 Have you read the Code of Conduct?"
- options:
- - label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
- required: true
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature.yaml b/.github/ISSUE_TEMPLATE/feature.yaml
deleted file mode 100644
index 2fe6df3..0000000
--- a/.github/ISSUE_TEMPLATE/feature.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: 🚀 Feature
-description: "Submit a proposal for a new feature"
-title: "🚀 Feature: "
-labels: [feature]
-body:
- - type: markdown
- attributes:
- value: |
- Thanks for taking the time to fill out our feature request form 🙏
- - type: textarea
- id: feature-description
- validations:
- required: true
- attributes:
- label: "🔖 Feature description"
- description: "A clear and concise description of what the feature is."
- placeholder: "You should add ..."
- - type: textarea
- id: pitch
- validations:
- required: true
- attributes:
- label: "🎤 Pitch"
- description: "Please explain why this feature should be implemented and how it would be used. Add examples, if applicable."
- placeholder: "In my use-case, ..."
- - type: checkboxes
- id: no-duplicate-issues
- attributes:
- label: "👀 Have you spent some time to check if this issue has been raised before?"
- description: "Have you Googled for a similar issue or checked our older issues for a similar bug?"
- options:
- - label: "I checked and didn't find similar issue"
- required: true
- - type: checkboxes
- id: read-code-of-conduct
- attributes:
- label: "🏢 Have you read the Code of Conduct?"
- options:
- - label: "I have read the [Code of Conduct](https://github.com/appwrite/appwrite/blob/HEAD/CODE_OF_CONDUCT.md)"
- required: true
\ No newline at end of file
diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml
new file mode 100644
index 0000000..d74ebb5
--- /dev/null
+++ b/.github/workflows/npm-publish.yml
@@ -0,0 +1,41 @@
+name: Publish Package to npmjs
+on:
+ release:
+ types: [published]
+jobs:
+ build-for-linux-and-windows:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v2
+ with:
+ node-version: '16.x'
+ registry-url: 'https://registry.npmjs.org'
+ - name: Setup binfmt with QEMU
+ run: |
+ sudo apt install qemu binfmt-support qemu-user-static
+ update-binfmts --display
+ - name: Setup ldid
+ run: |
+ git clone https://github.com/tpoechtrager/ldid
+ cd ./ldid
+ sudo make
+ sudo make install
+ - name: Install dependenices and build for Linux and Windows
+ run: |
+ npm install
+ npm run linux-x64
+ npm run linux-arm64
+ npm run windows-x64
+ npm run windows-arm64
+ npm run mac-x64
+ npm run mac-arm64
+ - name: Publish NPM library
+ run: npm publish
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+ - uses: fnkr/github-action-ghr@v1
+ env:
+ GHR_PATH: build/
+ GHR_REPLACE: false
+ GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5e37476
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+node_modules/
+build/
+.DS_Store
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index bd49ea5..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-os: linux
-dist: xenial
-
-language: shell
-
-services:
-- docker
-
-before_install:
-- curl -fsSL https://get.docker.com | sh
-- echo '{"experimental":"enabled"}' | sudo tee /etc/docker/daemon.json
-- mkdir -p $HOME/.docker
-- echo '{"experimental":"enabled"}' | sudo tee $HOME/.docker/config.json
-- sudo service docker start
-- >
- if [ ! -z "${DOCKERHUB_PULL_USERNAME:-}" ]; then
- echo "${DOCKERHUB_PULL_PASSWORD}" | docker login --username "${DOCKERHUB_PULL_USERNAME}" --password-stdin
- fi
-- docker --version
-- docker run --rm --privileged linuxkit/binfmt:v0.8
-- docker buildx create --use
-
-script:
-- docker ps; docker buildx ls
-
-deploy:
- - provider: script
- edge: true
- script: docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7,linux/ppc64le,linux/s390x -t appwrite/cli:$TRAVIS_TAG ./ --push
- on:
- tags: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index fa4d35e..0000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1 +0,0 @@
-# Change Log
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 3f2b154..0000000
--- a/Dockerfile
+++ /dev/null
@@ -1,20 +0,0 @@
-FROM composer:2.0 as step0
-
-WORKDIR /usr/local/code/
-COPY composer.json /usr/local/code/
-RUN composer update --ignore-platform-reqs --optimize-autoloader \
- --no-plugins --no-scripts --prefer-dist \
- `if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
-
-
-FROM php:7.4-alpine
-
-WORKDIR /usr/local/code/
-# Add Source Code
-COPY ./app /usr/local/code/app
-COPY ./src /usr/local/code/src
-COPY ./bin /usr/local/bin
-COPY --from=step0 /usr/local/code/vendor /usr/local/code/vendor
-
-# Executables
-RUN chmod -R +x /usr/local/bin/
\ No newline at end of file
diff --git a/Formula/appwrite.rb b/Formula/appwrite.rb
new file mode 100644
index 0000000..756a81e
--- /dev/null
+++ b/Formula/appwrite.rb
@@ -0,0 +1,19 @@
+require "language/node"
+
+class Appwrite < Formula
+ desc "CLI is a Node based command-line tool for Appwrite API"
+ homepage "https://appwrite.io"
+ license "BSD-3-Clause"
+ head "https://github.com/appwrite/sdk-for-cli.git", branch: "main"
+
+ depends_on "node"
+
+ def install
+ system "npm", "install", *Language::Node.std_npm_install_args(libexec)
+ bin.install_symlink Dir["#{libexec}/bin/*"]
+ end
+
+ test do
+ system "true"
+ end
+end
\ No newline at end of file
diff --git a/LICENSE b/LICENSE.md
similarity index 100%
rename from LICENSE
rename to LICENSE.md
diff --git a/README.md b/README.md
index b73168f..a6cd892 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
# Appwrite Command Line SDK
![License](https://img.shields.io/github/license/appwrite/sdk-for-cli.svg?style=flat-square)
-![Version](https://img.shields.io/badge/api%20version-0.12.0-blue.svg?style=flat-square)
+![Version](https://img.shields.io/badge/api%20version-0.12.3-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
-**This SDK is compatible with Appwrite server version 0.12.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-cli/releases).**
+**This SDK is compatible with Appwrite server version latest. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-cli/releases).**
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Command Line SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
@@ -14,87 +14,53 @@ Appwrite is an open-source backend as a service server that abstract and simplif
## Installation
-This tutorial assumes that you have docker setup and running on your machine.
+The Appwrite CLI is a Node based command line tool to help you interact with the Appwrite API. The CLI is distributed both as an [`npm package`](https://www.npmjs.com/package/appwrite-cli) as well as [pre built binaries](https://github.com/appwrite/sdk-for-cli/releases/latest) for specific operating systems and architectures.
-You can install the CLI by getting our installation script.
+### Install using NPM
+---
-### Linux / MacOS
-```bash
-$ wget -q https://appwrite.io/cli/install.sh -O - | /bin/bash
-```
-
-### Windows
-```powershell
-$ iwr -useb https://appwrite.io/cli/install.ps1 | iex
-```
+If you have `npm` installed, it's as easy as running
-## Initialisation
-The CLI needs to be initialised with your project settings. This can be done using
```sh
-$ appwrite init
+$ npm install -g appwrite-cli
```
-The CLI requires an endpoint, project ID, API key and a locale to be able to communicate with the Appwrite backend server. There are two ways to achieve this
-
-### 1. Pass in the project settings along with `appwrite init`
+Once the installation is complete, you can verify the install using
```sh
-$ appwrite init --endpoint="YOUR ENDPOINT" --project="YOUR PROJECT ID" --key="YOUR API KEY" --locale="YOUR LOCALE"
+$ appwrite -v
+0.14.0
```
-If any of the required values are missing, a prompt will show up, asking for those missing values.
+### Install using prebuilt binaries
+---
-### 2. Using the prompt
+If you do not have `npm` installed, you can always install the prebuilt binaries for your architecture and OS using our convenient installation scripts.
-Invoking `appwrite init` without any params triggers an interactive prompt where you can manually enter the details. These values are saved locally so that you dont have to re-enter them everytime.
-
-### Note
-By default, requests to domains with self signed SSL certificates (or no certificates) are disabled. If you trust the domain, you can bypass the certificate validation by using
-```sh
-$ appwrite client setSelfSigned --value=true
-```
-
-## Usage
-
-The Appwrite CLI follows the following general syntax.
-```sh
-$ appwrite [SERVICE] [COMMAND] --[OPTIONS]
+### Linux / MacOS Terminal
+```bash
+$ wget -q https://appwrite.io/cli/install.sh -O - | /bin/bash
```
-A few sample commands to get you started
-
-```sh
-$ appwrite users create --email="hello@appwrite.io" --password="very_strong_password"
-$ appwrite users list
+### MacOS via [Homebrew](https://brew.sh)
+```bash
+$ brew tap appwrite/sdk-for-cli https://github.com/appwrite/sdk-for-cli
+$ brew update
+$ brew install --HEAD appwrite
```
+> Please note that `--HEAD` will be removed with official release.
-To create a Document you can use the following command
-```sh
-$ appwrite database createDocument --collectionId="YOUR COLLECTION ID" --data='A VALID JSON STRING' --read=role:member --read="*" --write=role:guest
+### Windows
+```powershell
+$ iwr -useb https://appwrite.io/cli/install.ps1 | iex
```
-### Some Gotchas
-- `data` expects the JSON string to be escaped.
-- If using the wildcard (`*`) read or write permissions , make sure that it is properly escaped using a `\` or by enclosing it in `"*"` since bash interprets them differently.
-- Some arguments like `read` and `write` permissions are expected to be arrays. In the Appwrite CLI, arrays are passed by simply repeating the argument as seen in the `createDocument` example above.
-
-To get information about the different services available, you can use
-```sh
-$ appwrite help
+Once the installation completes, you can verify your install using
```
-
-To get information about a particular service and the commands available in a service you can use
-```sh
-$ appwrite users help
-$ appwrite accounts help
+$ appwrite -v
+0.14.0
```
-To get information about a particular command and the parameters it accepts, you can use
-
-```sh
-$ appwrite users list --help
-$ appwrite account get --help
-```
## Contribution
@@ -102,51 +68,35 @@ This library is auto-generated by Appwrite custom [SDK Generator](https://github
To build and test the CLI for development, follow these steps
-1. Clone the SDK Generator
+1. Clone the SDK Generator repository and cd into the directory
```sh
$ git clone https://github.com/appwrite/sdk-generator
+$ cd sdk-generator
```
-2. Ensure that docker is running locally and then run
+2. Ensure Docker is running locally and then install the composer dependencies using
```sh
-$ cd sdk-generator
-
-# Install the composer dependencies
$ docker run --rm --interactive --tty --volume "$(pwd)":/app composer install --ignore-platform-reqs --optimize-autoloader --no-plugins --no-scripts --prefer-dist
# Generate the SDKs
$ docker run --rm -v $(pwd):/app -w /app php:7.4-cli php example.php
```
-3. Head over to the generated SDK and build the CLI docker image
+3. Head over to the generated SDK and install the dependencies.
```sh
-$ cd examples/CLI
-$ docker build -t appwrite/cli .
+$ cd examples/cli
+$ npm install
```
-4. Install the CLI
-
-MacOS and Linux
-
-Open `install.sh` and change [this line](https://github.com/appwrite/sdk-for-cli/blob/master/install.sh#L33) to `APPWRITE_CLI_IMAGE_VERSION=latest` and
-comment [these lines](https://github.com/appwrite/sdk-for-cli/blob/master/install.sh#L119-L123).
-
-You can now install the CLI using
+4. Install the CLI using
```sh
-$ chmod +x install.sh
-$ ./install.sh
+$ npm install -g .
```
-Windows
-
-Open `install.ps1` and change [this line](https://github.com/appwrite/sdk-for-cli/blob/master/install.ps1#L28) to `APPWRITE_CLI_IMAGE_VERSION=latest` and
-comment [these lines](https://github.com/appwrite/sdk-for-cli/blob/master/install.ps1#L85-L89)
-
-You can now install the CLI using
+5. You can now use the CLI
```sh
-$ ./install.ps1
+$ appwrite -v
```
-
## License
Please see the [BSD-3-Clause license](https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE) file for more information.
\ No newline at end of file
diff --git a/app/account.php b/app/account.php
deleted file mode 100644
index 860bea3..0000000
--- a/app/account.php
+++ /dev/null
@@ -1,384 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite account {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('get')
- ->label('description', "Get currently logged in user data as JSON object.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/account');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('delete')
- ->label('description', "Delete a currently logged in user account. Behind the scene, the user record is not deleted but permanently blocked from any access. This is done to avoid deleted accounts being overtaken by new users with the same email address. Any user-related resources like documents or storage files should be deleted separately.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/account');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateEmail')
- ->label('description', "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.
-This endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.
-\n\n")
- ->param('email', '' , new Wildcard() , 'User email.', false)
- ->param('password', '' , new Wildcard() , 'User password. Must be at least 8 chars.', false)
- ->action(function ( $email, $password ) use ($parser) {
- /** @var string $email */
- /** @var string $password */
-
- $client = new Client();
- $path = str_replace([], [], '/account/email');
- $params = [];
- /** Body Params */
- $params['email'] = $email;
- $params['password'] = $password;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getLogs')
- ->label('description', "Get currently logged in user list of latest security activity logs. Each log returns user IP address, location and date and time of log.\n\n")
- ->param('limit', 25 , new Wildcard() , 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->action(function ( $limit, $offset ) use ($parser) {
- /** @var integer $limit */
- /** @var integer $offset */
-
- $client = new Client();
- $path = str_replace([], [], '/account/logs');
- $params = [];
- /** Query Params */
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateName')
- ->label('description', "Update currently logged in user account name.\n\n")
- ->param('name', '' , new Wildcard() , 'User name. Max length: 128 chars.', false)
- ->action(function ( $name ) use ($parser) {
- /** @var string $name */
-
- $client = new Client();
- $path = str_replace([], [], '/account/name');
- $params = [];
- /** Body Params */
- $params['name'] = $name;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updatePassword')
- ->label('description', "Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth and Team Invites, oldPassword is optional.\n\n")
- ->param('password', '' , new Wildcard() , 'New user password. Must be at least 8 chars.', false)
- ->param('oldPassword', '' , new Wildcard() , 'Current user password. Must be at least 8 chars.', true)
- ->action(function ( $password, $oldPassword ) use ($parser) {
- /** @var string $password */
- /** @var string $oldPassword */
-
- $client = new Client();
- $path = str_replace([], [], '/account/password');
- $params = [];
- /** Body Params */
- $params['password'] = $password;
- $params['oldPassword'] = $oldPassword;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getPrefs')
- ->label('description', "Get currently logged in user preferences as a key-value object.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/account/prefs');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updatePrefs')
- ->label('description', "Update currently logged in user account preferences. You can pass only the specific settings you wish to update.\n\n")
- ->param('prefs', '' , new Wildcard() , 'Prefs key-value JSON object.', false)
- ->action(function ( $prefs ) use ($parser) {
- /** @var object $prefs */
-
- $client = new Client();
- $path = str_replace([], [], '/account/prefs');
- $params = [];
- /** Body Params */
- $params['prefs'] = \json_decode($prefs);
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createRecovery')
- ->label('description', "Sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link he is redirected back to your app password reset URL with the secret key and email address values attached to the URL query string. Use the query string params to submit a request to the [PUT /account/recovery](/docs/client/account#accountUpdateRecovery) endpoint to complete the process. The verification link sent to the user's email address is valid for 1 hour.\n\n")
- ->param('email', '' , new Wildcard() , 'User email.', false)
- ->param('url', '' , new Wildcard() , 'URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false)
- ->action(function ( $email, $url ) use ($parser) {
- /** @var string $email */
- /** @var string $url */
-
- $client = new Client();
- $path = str_replace([], [], '/account/recovery');
- $params = [];
- /** Body Params */
- $params['email'] = $email;
- $params['url'] = $url;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateRecovery')
- ->label('description', "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST /account/recovery](/docs/client/account#accountCreateRecovery) endpoint.
-
-Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('secret', '' , new Wildcard() , 'Valid reset token.', false)
- ->param('password', '' , new Wildcard() , 'New user password. Must be at least 8 chars.', false)
- ->param('passwordAgain', '' , new Wildcard() , 'Repeat new user password. Must be at least 8 chars.', false)
- ->action(function ( $userId, $secret, $password, $passwordAgain ) use ($parser) {
- /** @var string $userId */
- /** @var string $secret */
- /** @var string $password */
- /** @var string $passwordAgain */
-
- $client = new Client();
- $path = str_replace([], [], '/account/recovery');
- $params = [];
- /** Body Params */
- $params['userId'] = $userId;
- $params['secret'] = $secret;
- $params['password'] = $password;
- $params['passwordAgain'] = $passwordAgain;
- $response = $client->call(Client::METHOD_PUT, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getSessions')
- ->label('description', "Get currently logged in user list of active sessions across different devices.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/account/sessions');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteSessions')
- ->label('description', "Delete all sessions from the user account and remove any sessions cookies from the end client.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/account/sessions');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getSession')
- ->label('description', "Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used.\n\n")
- ->param('sessionId', '' , new Wildcard() , 'Session ID. Use the string 'current' to get the current device session.', false)
- ->action(function ( $sessionId ) use ($parser) {
- /** @var string $sessionId */
-
- $client = new Client();
- $path = str_replace(['{sessionId}'], [$sessionId], '/account/sessions/{sessionId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteSession')
- ->label('description', "Use this endpoint to log out the currently logged in user from all their account sessions across all of their different devices. When using the option id argument, only the session unique ID provider will be deleted.\n\n")
- ->param('sessionId', '' , new Wildcard() , 'Session ID. Use the string 'current' to delete the current device session.', false)
- ->action(function ( $sessionId ) use ($parser) {
- /** @var string $sessionId */
-
- $client = new Client();
- $path = str_replace(['{sessionId}'], [$sessionId], '/account/sessions/{sessionId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createVerification')
- ->label('description', "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](/docs/client/account#accountUpdateVerification). The verification link sent to the user's email address is valid for 7 days.
-
-Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.
-\n\n")
- ->param('url', '' , new Wildcard() , 'URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false)
- ->action(function ( $url ) use ($parser) {
- /** @var string $url */
-
- $client = new Client();
- $path = str_replace([], [], '/account/verification');
- $params = [];
- /** Body Params */
- $params['url'] = $url;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateVerification')
- ->label('description', "Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('secret', '' , new Wildcard() , 'Valid verification token.', false)
- ->action(function ( $userId, $secret ) use ($parser) {
- /** @var string $userId */
- /** @var string $secret */
-
- $client = new Client();
- $path = str_replace([], [], '/account/verification');
- $params = [];
- /** Body Params */
- $params['userId'] = $userId;
- $params['secret'] = $secret;
- $response = $client->call(Client::METHOD_PUT, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite account [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "get" => "Get currently logged in user data as JSON object.",
- "delete" => "Delete a currently logged in user account. Behind the scene, the user record is not deleted but permanently blocked from any access. This is done to avoid deleted accounts being overtaken by new users with the same email address. Any user-related resources like documents or storage files should be deleted separately.",
- "updateEmail" => "Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request.
-This endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password.
-",
- "getLogs" => "Get currently logged in user list of latest security activity logs. Each log returns user IP address, location and date and time of log.",
- "updateName" => "Update currently logged in user account name.",
- "updatePassword" => "Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth and Team Invites, oldPassword is optional.",
- "getPrefs" => "Get currently logged in user preferences as a key-value object.",
- "updatePrefs" => "Update currently logged in user account preferences. You can pass only the specific settings you wish to update.",
- "createRecovery" => "Sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link he is redirected back to your app password reset URL with the secret key and email address values attached to the URL query string. Use the query string params to submit a request to the [PUT /account/recovery](/docs/client/account#accountUpdateRecovery) endpoint to complete the process. The verification link sent to the user's email address is valid for 1 hour.",
- "updateRecovery" => "Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST /account/recovery](/docs/client/account#accountCreateRecovery) endpoint.
-
-Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.",
- "getSessions" => "Get currently logged in user list of active sessions across different devices.",
- "deleteSessions" => "Delete all sessions from the user account and remove any sessions cookies from the end client.",
- "getSession" => "Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used.",
- "deleteSession" => "Use this endpoint to log out the currently logged in user from all their account sessions across all of their different devices. When using the option id argument, only the session unique ID provider will be deleted.",
- "createVerification" => "Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](/docs/client/account#accountUpdateVerification). The verification link sent to the user's email address is valid for 7 days.
-
-Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.
-",
- "updateVerification" => "Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite account COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/avatars.php b/app/avatars.php
deleted file mode 100644
index 0fd4f58..0000000
--- a/app/avatars.php
+++ /dev/null
@@ -1,256 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite avatars {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('getBrowser')
- ->label('description', "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user /account/sessions endpoint. Use width, height and quality arguments to change the output settings.\n\n")
- ->param('code', '' , new Wildcard() , 'Browser Code.', false)
- ->param('width', 100 , new Wildcard() , 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('height', 100 , new Wildcard() , 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('quality', 100 , new Wildcard() , 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
- ->action(function ( $code, $width, $height, $quality ) use ($parser) {
- /** @var string $code */
- /** @var integer $width */
- /** @var integer $height */
- /** @var integer $quality */
-
- $client = new Client();
- $path = str_replace(['{code}'], [$code], '/avatars/browsers/{code}');
- $params = [];
- /** Query Params */
- $params['width'] = $width;
- $params['height'] = $height;
- $params['quality'] = $quality;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getCreditCard')
- ->label('description', "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.\n\n")
- ->param('code', '' , new Wildcard() , 'Credit Card Code. Possible values: amex, argencard, cabal, censosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.', false)
- ->param('width', 100 , new Wildcard() , 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('height', 100 , new Wildcard() , 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('quality', 100 , new Wildcard() , 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
- ->action(function ( $code, $width, $height, $quality ) use ($parser) {
- /** @var string $code */
- /** @var integer $width */
- /** @var integer $height */
- /** @var integer $quality */
-
- $client = new Client();
- $path = str_replace(['{code}'], [$code], '/avatars/credit-cards/{code}');
- $params = [];
- /** Query Params */
- $params['width'] = $width;
- $params['height'] = $height;
- $params['quality'] = $quality;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getFavicon')
- ->label('description', "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.
-\n\n")
- ->param('url', '' , new Wildcard() , 'Website URL which you want to fetch the favicon from.', false)
- ->action(function ( $url ) use ($parser) {
- /** @var string $url */
-
- $client = new Client();
- $path = str_replace([], [], '/avatars/favicon');
- $params = [];
- /** Query Params */
- $params['url'] = $url;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getFlag')
- ->label('description', "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings.\n\n")
- ->param('code', '' , new Wildcard() , 'Country Code. ISO Alpha-2 country code format.', false)
- ->param('width', 100 , new Wildcard() , 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('height', 100 , new Wildcard() , 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('quality', 100 , new Wildcard() , 'Image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
- ->action(function ( $code, $width, $height, $quality ) use ($parser) {
- /** @var string $code */
- /** @var integer $width */
- /** @var integer $height */
- /** @var integer $quality */
-
- $client = new Client();
- $path = str_replace(['{code}'], [$code], '/avatars/flags/{code}');
- $params = [];
- /** Query Params */
- $params['width'] = $width;
- $params['height'] = $height;
- $params['quality'] = $quality;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getImage')
- ->label('description', "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.\n\n")
- ->param('url', '' , new Wildcard() , 'Image URL which you want to crop.', false)
- ->param('width', 400 , new Wildcard() , 'Resize preview image width, Pass an integer between 0 to 2000.', true)
- ->param('height', 400 , new Wildcard() , 'Resize preview image height, Pass an integer between 0 to 2000.', true)
- ->action(function ( $url, $width, $height ) use ($parser) {
- /** @var string $url */
- /** @var integer $width */
- /** @var integer $height */
-
- $client = new Client();
- $path = str_replace([], [], '/avatars/image');
- $params = [];
- /** Query Params */
- $params['url'] = $url;
- $params['width'] = $width;
- $params['height'] = $height;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getInitials')
- ->label('description', "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.
-
-You can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.\n\n")
- ->param('name', '' , new Wildcard() , 'Full Name. When empty, current user name or email will be used. Max length: 128 chars.', true)
- ->param('width', 500 , new Wildcard() , 'Image width. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('height', 500 , new Wildcard() , 'Image height. Pass an integer between 0 to 2000. Defaults to 100.', true)
- ->param('color', '' , new Wildcard() , 'Changes text color. By default a random color will be picked and stay will persistent to the given name.', true)
- ->param('background', '' , new Wildcard() , 'Changes background color. By default a random color will be picked and stay will persistent to the given name.', true)
- ->action(function ( $name, $width, $height, $color, $background ) use ($parser) {
- /** @var string $name */
- /** @var integer $width */
- /** @var integer $height */
- /** @var string $color */
- /** @var string $background */
-
- $client = new Client();
- $path = str_replace([], [], '/avatars/initials');
- $params = [];
- /** Query Params */
- $params['name'] = $name;
- $params['width'] = $width;
- $params['height'] = $height;
- $params['color'] = $color;
- $params['background'] = $background;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getQR')
- ->label('description', "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.\n\n")
- ->param('text', '' , new Wildcard() , 'Plain text to be converted to QR code image.', false)
- ->param('size', 400 , new Wildcard() , 'QR code size. Pass an integer between 0 to 1000. Defaults to 400.', true)
- ->param('margin', 1 , new Wildcard() , 'Margin from edge. Pass an integer between 0 to 10. Defaults to 1.', true)
- ->param('download', false , new Wildcard() , 'Return resulting image with 'Content-Disposition: attachment ' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.', true)
- ->action(function ( $text, $size, $margin, $download ) use ($parser) {
- /** @var string $text */
- /** @var integer $size */
- /** @var integer $margin */
- /** @var boolean $download */
-
- $client = new Client();
- $path = str_replace([], [], '/avatars/qr');
- $params = [];
- /** Query Params */
- $params['text'] = $text;
- $params['size'] = $size;
- $params['margin'] = $margin;
- $params['download'] = $download;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite avatars [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "getBrowser" => "You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user /account/sessions endpoint. Use width, height and quality arguments to change the output settings.",
- "getCreditCard" => "The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.",
- "getFavicon" => "Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL.
-",
- "getFlag" => "You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings.",
- "getImage" => "Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.",
- "getInitials" => "Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned.
-
-You can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.",
- "getQR" => "Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite avatars COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/client.php b/app/client.php
deleted file mode 100644
index 4c23c82..0000000
--- a/app/client.php
+++ /dev/null
@@ -1,143 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite client {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('setEndpoint')
- ->param('endpoint', '', new Wildcard(), 'Your Appwrite endpoint', false)
- ->action(function($endpoint) use ($client) {
- $result = $client->setPreference('endpoint', $endpoint)
- ->savePreferences();
- if ($result === false) {
- Console::error('❌ Could not save preferences.');
- } else {
- Console::success('✅ Preferences saved successfully');
- }
- });
-
-$cli
- ->task('setSelfSigned')
- ->param('value', '', new Wildcard(), 'A boolean representing whether you are using a self signed certificate', false)
- ->action(function($value) use ($client) {
- $result = $client->setPreference('selfSigned', $value)
- ->savePreferences();
- if ($result === false) {
- Console::error('❌ Could not save preferences.');
- } else {
- Console::success('✅ Preferences saved successfully');
- }
- });
-
-
-$cli
- ->task('setProject')
- ->param('project', '', new Wildcard(), 'Your project ID', false)
- ->action(function($project) use ($client) {
- $result = $client->setPreference('X-Appwrite-Project', $project)
- ->savePreferences();
- if ($result === false) {
- Console::error('❌ Could not save preferences.');
- } else {
- Console::success('✅ Preferences saved successfully');
- }
- });
-$cli
- ->task('setKey')
- ->param('key', '', new Wildcard(), 'Your secret API key', false)
- ->action(function($key) use ($client) {
- $result = $client->setPreference('X-Appwrite-Key', $key)
- ->savePreferences();
- if ($result === false) {
- Console::error('❌ Could not save preferences.');
- } else {
- Console::success('✅ Preferences saved successfully');
- }
- });
-$cli
- ->task('setLocale')
- ->param('locale', '', new Wildcard(), '', false)
- ->action(function($locale) use ($client) {
- $result = $client->setPreference('X-Appwrite-Locale', $locale)
- ->savePreferences();
- if ($result === false) {
- Console::error('❌ Could not save preferences.');
- } else {
- Console::success('✅ Preferences saved successfully');
- }
- });
-
-$cli
- ->task('version')
- ->action(function() {
- Console::log('CLI Version : 0.13.1');
- Console::log('Server Version : 0.12.0');
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite client [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "setEndpoint" => "Set your server endpoint.",
- "setProject" => "Set the project you want to connect to.",
- "setKey" => "Set the API key for the project.",
- "setLocale" => "Set your preferred locale (eg: en-US).",
- "setSelfSigned" => "Set whether you are using a self signed certificate",
- "version" => "Get the current cli version"
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite client COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
\ No newline at end of file
diff --git a/app/database.php b/app/database.php
deleted file mode 100644
index 0f15a71..0000000
--- a/app/database.php
+++ /dev/null
@@ -1,746 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite database {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('listCollections')
- ->label('description', "Get a list of all the user collections. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's collections. [Learn more about different API modes](/docs/admin).\n\n")
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of collection to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the collection used as the starting point for the query, excluding the collection itself. Should be used for efficient pagination when working with large sets of data.', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace([], [], '/database/collections');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createCollection')
- ->label('description', "Create a new Collection.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Unique Id. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.', false)
- ->param('name', '' , new Wildcard() , 'Collection name. Max length: 128 chars.', false)
- ->param('permission', '' , new Wildcard() , 'Permissions type model to use for reading documents in this collection. You can use collection-level permission set once on the collection using the `read` and `write` params, or you can set document-level permission where each document read and write params will decide who has access to read and write to each document individually. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->param('read', '' , new Wildcard() , 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->param('write', '' , new Wildcard() , 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->action(function ( $collectionId, $name, $permission, $read, $write ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $name */
- /** @var string $permission */
- /** @var array $read */
- /** @var array $write */
-
- $client = new Client();
- $path = str_replace([], [], '/database/collections');
- $params = [];
- /** Body Params */
- $params['collectionId'] = $collectionId;
- $params['name'] = $name;
- $params['permission'] = $permission;
- $params['read'] = !is_array($read) ? array($read) : $read;
- $params['write'] = !is_array($write) ? array($write) : $write;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getCollection')
- ->label('description', "Get a collection by its unique ID. This endpoint response returns a JSON object with the collection metadata.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID.', false)
- ->action(function ( $collectionId ) use ($parser) {
- /** @var string $collectionId */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateCollection')
- ->label('description', "Update a collection by its unique ID.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID.', false)
- ->param('name', '' , new Wildcard() , 'Collection name. Max length: 128 chars.', false)
- ->param('permission', '' , new Wildcard() , 'Permissions type model to use for reading documents in this collection. You can use collection-level permission set once on the collection using the `read` and `write` params, or you can set document-level permission where each document read and write params will decide who has access to read and write to each document individually. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->param('read', [] , new Wildcard() , 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->param('write', [] , new Wildcard() , 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->param('enabled', true , new Wildcard() , 'Is collection enabled?', true)
- ->action(function ( $collectionId, $name, $permission, $read, $write, $enabled ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $name */
- /** @var string $permission */
- /** @var array $read */
- /** @var array $write */
- /** @var boolean $enabled */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}');
- $params = [];
- /** Body Params */
- $params['name'] = $name;
- $params['permission'] = $permission;
- $params['read'] = !is_array($read) ? array($read) : $read;
- $params['write'] = !is_array($write) ? array($write) : $write;
- $params['enabled'] = $enabled;
- $response = $client->call(Client::METHOD_PUT, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteCollection')
- ->label('description', "Delete a collection by its unique ID. Only users with write permissions have access to delete this resource.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID.', false)
- ->action(function ( $collectionId ) use ($parser) {
- /** @var string $collectionId */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('listAttributes')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->action(function ( $collectionId ) use ($parser) {
- /** @var string $collectionId */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createBooleanAttribute')
- ->label('description', "Create a boolean attribute.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('xdefault', null , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $required, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var boolean $required */
- /** @var boolean $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/boolean');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['required'] = $required;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createEmailAttribute')
- ->label('description', "Create an email attribute.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('xdefault', '' , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $required, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var boolean $required */
- /** @var string $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/email');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['required'] = $required;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createEnumAttribute')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('elements', '' , new Wildcard() , 'Array of elements in enumerated type. Uses length of longest element to determine size.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('xdefault', '' , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $elements, $required, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var array $elements */
- /** @var boolean $required */
- /** @var string $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/enum');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['elements'] = !is_array($elements) ? array($elements) : $elements;
- $params['required'] = $required;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createFloatAttribute')
- ->label('description', "Create a float attribute. Optionally, minimum and maximum values can be provided.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('min', '' , new Wildcard() , 'Minimum value to enforce on new documents', true)
- ->param('max', '' , new Wildcard() , 'Maximum value to enforce on new documents', true)
- ->param('xdefault', '' , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $required, $min, $max, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var boolean $required */
- /** @var string $min */
- /** @var string $max */
- /** @var string $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/float');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['required'] = $required;
- $params['min'] = $min;
- $params['max'] = $max;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createIntegerAttribute')
- ->label('description', "Create an integer attribute. Optionally, minimum and maximum values can be provided.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('min', null , new Wildcard() , 'Minimum value to enforce on new documents', true)
- ->param('max', null , new Wildcard() , 'Maximum value to enforce on new documents', true)
- ->param('xdefault', null , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $required, $min, $max, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var boolean $required */
- /** @var integer $min */
- /** @var integer $max */
- /** @var integer $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/integer');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['required'] = $required;
- $params['min'] = (int)$min;
- $params['max'] = (int)$max;
- $params['default'] = (int)$xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createIpAttribute')
- ->label('description', "Create IP address attribute.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('xdefault', '' , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $required, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var boolean $required */
- /** @var string $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/ip');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['required'] = $required;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createStringAttribute')
- ->label('description', "Create a string attribute.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('size', '' , new Wildcard() , 'Attribute size for text attributes, in number of characters.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('xdefault', '' , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $size, $required, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var integer $size */
- /** @var boolean $required */
- /** @var string $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/string');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['size'] = (int)$size;
- $params['required'] = $required;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createUrlAttribute')
- ->label('description', "Create a URL attribute.
-\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->param('required', '' , new Wildcard() , 'Is attribute required?', false)
- ->param('xdefault', '' , new Wildcard() , 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
- ->param('xarray', false , new Wildcard() , 'Is attribute an array?', true)
- ->action(function ( $collectionId, $key, $required, $xdefault, $xarray ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var boolean $required */
- /** @var string $xdefault */
- /** @var boolean $xarray */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/attributes/url');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['required'] = $required;
- $params['default'] = $xdefault;
- $params['array'] = $xarray;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getAttribute')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->action(function ( $collectionId, $key ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{key}'], [$collectionId, $key], '/database/collections/{collectionId}/attributes/{key}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteAttribute')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Attribute Key.', false)
- ->action(function ( $collectionId, $key ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{key}'], [$collectionId, $key], '/database/collections/{collectionId}/attributes/{key}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('listDocuments')
- ->label('description', "Get a list of all the user documents. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's documents. [Learn more about different API modes](/docs/admin).\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('queries', [] , new Wildcard() , 'Array of query strings.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of documents to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the document used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderAttributes', [] , new Wildcard() , 'Array of attributes used to sort results.', true)
- ->param('orderTypes', [] , new Wildcard() , 'Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order.', true)
- ->action(function ( $collectionId, $queries, $limit, $offset, $cursor, $cursorDirection, $orderAttributes, $orderTypes ) use ($parser) {
- /** @var string $collectionId */
- /** @var array $queries */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var array $orderAttributes */
- /** @var array $orderTypes */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/documents');
- $params = [];
- /** Query Params */
- $params['queries'] = !is_array($queries) ? array($queries) : $queries;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderAttributes'] = !is_array($orderAttributes) ? array($orderAttributes) : $orderAttributes;
- $params['orderTypes'] = !is_array($orderTypes) ? array($orderTypes) : $orderTypes;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createDocument')
- ->label('description', "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](/docs/server/database#databaseCreateCollection) API or directly from your database console.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection with validation rules using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('documentId', '' , new Wildcard() , 'Document ID. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.', false)
- ->param('data', '' , new Wildcard() , 'Document data as JSON object.', false)
- ->param('read', [] , new Wildcard() , 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->param('write', [] , new Wildcard() , 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->action(function ( $collectionId, $documentId, $data, $read, $write ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $documentId */
- /** @var object $data */
- /** @var array $read */
- /** @var array $write */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/documents');
- $params = [];
- /** Body Params */
- $params['documentId'] = $documentId;
- $params['data'] = \json_decode($data);
- $params['read'] = !is_array($read) ? array($read) : $read;
- $params['write'] = !is_array($write) ? array($write) : $write;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getDocument')
- ->label('description', "Get a document by its unique ID. This endpoint response returns a JSON object with the document data.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('documentId', '' , new Wildcard() , 'Document ID.', false)
- ->action(function ( $collectionId, $documentId ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $documentId */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{documentId}'], [$collectionId, $documentId], '/database/collections/{collectionId}/documents/{documentId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateDocument')
- ->label('description', "Update a document by its unique ID. Using the patch method you can pass only specific fields that will get updated.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection with validation rules using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('documentId', '' , new Wildcard() , 'Document ID.', false)
- ->param('data', '' , new Wildcard() , 'Document data as JSON object.', false)
- ->param('read', [] , new Wildcard() , 'An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->param('write', [] , new Wildcard() , 'An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->action(function ( $collectionId, $documentId, $data, $read, $write ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $documentId */
- /** @var object $data */
- /** @var array $read */
- /** @var array $write */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{documentId}'], [$collectionId, $documentId], '/database/collections/{collectionId}/documents/{documentId}');
- $params = [];
- /** Body Params */
- $params['data'] = \json_decode($data);
- $params['read'] = !is_array($read) ? array($read) : $read;
- $params['write'] = !is_array($write) ? array($write) : $write;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteDocument')
- ->label('description', "Delete a document by its unique ID. This endpoint deletes only the parent documents, its attributes and relations to other documents. Child documents **will not** be deleted.\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('documentId', '' , new Wildcard() , 'Document ID.', false)
- ->action(function ( $collectionId, $documentId ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $documentId */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{documentId}'], [$collectionId, $documentId], '/database/collections/{collectionId}/documents/{documentId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('listIndexes')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->action(function ( $collectionId ) use ($parser) {
- /** @var string $collectionId */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/indexes');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createIndex')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Index Key.', false)
- ->param('type', '' , new Wildcard() , 'Index type.', false)
- ->param('attributes', '' , new Wildcard() , 'Array of attributes to index.', false)
- ->param('orders', [] , new Wildcard() , 'Array of index orders.', true)
- ->action(function ( $collectionId, $key, $type, $attributes, $orders ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
- /** @var string $type */
- /** @var array $attributes */
- /** @var array $orders */
-
- $client = new Client();
- $path = str_replace(['{collectionId}'], [$collectionId], '/database/collections/{collectionId}/indexes');
- $params = [];
- /** Body Params */
- $params['key'] = $key;
- $params['type'] = $type;
- $params['attributes'] = !is_array($attributes) ? array($attributes) : $attributes;
- $params['orders'] = !is_array($orders) ? array($orders) : $orders;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getIndex')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Index Key.', false)
- ->action(function ( $collectionId, $key ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{key}'], [$collectionId, $key], '/database/collections/{collectionId}/indexes/{key}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteIndex')
- ->label('description', "\n\n")
- ->param('collectionId', '' , new Wildcard() , 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).', false)
- ->param('key', '' , new Wildcard() , 'Index Key.', false)
- ->action(function ( $collectionId, $key ) use ($parser) {
- /** @var string $collectionId */
- /** @var string $key */
-
- $client = new Client();
- $path = str_replace(['{collectionId}', '{key}'], [$collectionId, $key], '/database/collections/{collectionId}/indexes/{key}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite database [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "listCollections" => "Get a list of all the user collections. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's collections. [Learn more about different API modes](/docs/admin).",
- "createCollection" => "Create a new Collection.",
- "getCollection" => "Get a collection by its unique ID. This endpoint response returns a JSON object with the collection metadata.",
- "updateCollection" => "Update a collection by its unique ID.",
- "deleteCollection" => "Delete a collection by its unique ID. Only users with write permissions have access to delete this resource.",
- "listAttributes" => "",
- "createBooleanAttribute" => "Create a boolean attribute.
-",
- "createEmailAttribute" => "Create an email attribute.
-",
- "createEnumAttribute" => "",
- "createFloatAttribute" => "Create a float attribute. Optionally, minimum and maximum values can be provided.
-",
- "createIntegerAttribute" => "Create an integer attribute. Optionally, minimum and maximum values can be provided.
-",
- "createIpAttribute" => "Create IP address attribute.
-",
- "createStringAttribute" => "Create a string attribute.
-",
- "createUrlAttribute" => "Create a URL attribute.
-",
- "getAttribute" => "",
- "deleteAttribute" => "",
- "listDocuments" => "Get a list of all the user documents. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's documents. [Learn more about different API modes](/docs/admin).",
- "createDocument" => "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](/docs/server/database#databaseCreateCollection) API or directly from your database console.",
- "getDocument" => "Get a document by its unique ID. This endpoint response returns a JSON object with the document data.",
- "updateDocument" => "Update a document by its unique ID. Using the patch method you can pass only specific fields that will get updated.",
- "deleteDocument" => "Delete a document by its unique ID. This endpoint deletes only the parent documents, its attributes and relations to other documents. Child documents **will not** be deleted.",
- "listIndexes" => "",
- "createIndex" => "",
- "getIndex" => "",
- "deleteIndex" => "",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite database COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/functions.php b/app/functions.php
deleted file mode 100644
index b75e229..0000000
--- a/app/functions.php
+++ /dev/null
@@ -1,438 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite functions {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('list')
- ->label('description', "Get a list of all the project's functions. You can use the query params to filter your results.\n\n")
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of functions to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace([], [], '/functions');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('create')
- ->label('description', "Create a new function. You can pass a list of [permissions](/docs/permissions) to allow different project users or team with access to execute the function using the client API.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.', false)
- ->param('name', '' , new Wildcard() , 'Function name. Max length: 128 chars.', false)
- ->param('execute', '' , new Wildcard() , 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->param('runtime', '' , new Wildcard() , 'Execution runtime.', false)
- ->param('vars', [] , new Wildcard() , 'Key-value JSON object that will be passed to the function as environment variables.', true)
- ->param('events', [] , new Wildcard() , 'Events list.', true)
- ->param('schedule', '' , new Wildcard() , 'Schedule CRON syntax.', true)
- ->param('timeout', 15 , new Wildcard() , 'Function maximum execution time in seconds.', true)
- ->action(function ( $functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout ) use ($parser) {
- /** @var string $functionId */
- /** @var string $name */
- /** @var array $execute */
- /** @var string $runtime */
- /** @var object $vars */
- /** @var array $events */
- /** @var string $schedule */
- /** @var integer $timeout */
-
- $client = new Client();
- $path = str_replace([], [], '/functions');
- $params = [];
- /** Body Params */
- $params['functionId'] = $functionId;
- $params['name'] = $name;
- $params['execute'] = !is_array($execute) ? array($execute) : $execute;
- $params['runtime'] = $runtime;
- $params['vars'] = \json_decode($vars);
- $params['events'] = !is_array($events) ? array($events) : $events;
- $params['schedule'] = $schedule;
- $params['timeout'] = (int)$timeout;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('listRuntimes')
- ->label('description', "Get a list of all runtimes that are currently active in your project.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/functions/runtimes');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('get')
- ->label('description', "Get a function by its unique ID.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->action(function ( $functionId ) use ($parser) {
- /** @var string $functionId */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('update')
- ->label('description', "Update function by its unique ID.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('name', '' , new Wildcard() , 'Function name. Max length: 128 chars.', false)
- ->param('execute', '' , new Wildcard() , 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->param('vars', [] , new Wildcard() , 'Key-value JSON object that will be passed to the function as environment variables.', true)
- ->param('events', [] , new Wildcard() , 'Events list.', true)
- ->param('schedule', '' , new Wildcard() , 'Schedule CRON syntax.', true)
- ->param('timeout', 15 , new Wildcard() , 'Maximum execution time in seconds.', true)
- ->action(function ( $functionId, $name, $execute, $vars, $events, $schedule, $timeout ) use ($parser) {
- /** @var string $functionId */
- /** @var string $name */
- /** @var array $execute */
- /** @var object $vars */
- /** @var array $events */
- /** @var string $schedule */
- /** @var integer $timeout */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}');
- $params = [];
- /** Body Params */
- $params['name'] = $name;
- $params['execute'] = !is_array($execute) ? array($execute) : $execute;
- $params['vars'] = \json_decode($vars);
- $params['events'] = !is_array($events) ? array($events) : $events;
- $params['schedule'] = $schedule;
- $params['timeout'] = (int)$timeout;
- $response = $client->call(Client::METHOD_PUT, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('delete')
- ->label('description', "Delete a function by its unique ID.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->action(function ( $functionId ) use ($parser) {
- /** @var string $functionId */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('listExecutions')
- ->label('description', "Get a list of all the current user function execution logs. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's executions. [Learn more about different API modes](/docs/admin).\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of executions to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->action(function ( $functionId, $limit, $offset, $search, $cursor, $cursorDirection ) use ($parser) {
- /** @var string $functionId */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $search */
- /** @var string $cursor */
- /** @var string $cursorDirection */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}/executions');
- $params = [];
- /** Query Params */
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['search'] = $search;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createExecution')
- ->label('description', "Trigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('data', '' , new Wildcard() , 'String of custom data to send to function.', true)
- ->action(function ( $functionId, $data ) use ($parser) {
- /** @var string $functionId */
- /** @var string $data */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}/executions');
- $params = [];
- /** Body Params */
- $params['data'] = $data;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getExecution')
- ->label('description', "Get a function execution log by its unique ID.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('executionId', '' , new Wildcard() , 'Execution ID.', false)
- ->action(function ( $functionId, $executionId ) use ($parser) {
- /** @var string $functionId */
- /** @var string $executionId */
-
- $client = new Client();
- $path = str_replace(['{functionId}', '{executionId}'], [$functionId, $executionId], '/functions/{functionId}/executions/{executionId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateTag')
- ->label('description', "Update the function code tag ID using the unique function ID. Use this endpoint to switch the code tag that should be executed by the execution endpoint.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('tag', '' , new Wildcard() , 'Tag ID.', false)
- ->action(function ( $functionId, $tag ) use ($parser) {
- /** @var string $functionId */
- /** @var string $tag */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}/tag');
- $params = [];
- /** Body Params */
- $params['tag'] = $tag;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('listTags')
- ->label('description', "Get a list of all the project's code tags. You can use the query params to filter your results.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of tags to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the tag used as the starting point for the query, excluding the tag itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $functionId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $functionId */
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}/tags');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createTag')
- ->label('description', "Create a new function code tag. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's tag to use your new tag UID.
-
-This endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](/docs/functions).
-
-Use the 'command' param to set the entry point used to execute your code.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('command', '' , new Wildcard() , 'Code execution command.', false)
- ->param('code', '' , new Wildcard() , 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
- ->action(function ( $functionId, $command, $code ) use ($parser) {
- /** @var string $functionId */
- /** @var string $command */
- /** @var file $code */
-
- $client = new Client();
- $path = str_replace(['{functionId}'], [$functionId], '/functions/{functionId}/tags');
- $params = [];
- /** Body Params */
- $params['command'] = $command;
- $code = \urldecode($code);
- $cloudFunctionPath = realpath(__DIR__.'/../files/'.$code);
- $cloudFunctionParentDir = escapeshellarg(dirname($cloudFunctionPath, 1));
- $cloudFunctionDirName = escapeshellarg(basename($cloudFunctionPath));
- if (file_exists($cloudFunctionPath) === false ) {
- throw new Exception("Path doesn't exist. Please ensure that the path is within the current directory. ");
- }
- $archiveName = 'code.tar.gz';
- $volumeMountPoint = realpath(__DIR__.'/../files/');
- exec("tar -zcvf $archiveName -C $cloudFunctionParentDir $cloudFunctionDirName && mv $archiveName $volumeMountPoint");
- $archivePath = realpath($volumeMountPoint."/$archiveName");
- $cFile = new \CURLFile($archivePath, 'application/x-gzip' , basename($archivePath));
- $params['code'] = $cFile;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'multipart/form-data',
- ], $params);
- $parser->parseResponse($response);
- unlink($archivePath);
- });
-
-$cli
- ->task('getTag')
- ->label('description', "Get a code tag by its unique ID.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('tagId', '' , new Wildcard() , 'Tag ID.', false)
- ->action(function ( $functionId, $tagId ) use ($parser) {
- /** @var string $functionId */
- /** @var string $tagId */
-
- $client = new Client();
- $path = str_replace(['{functionId}', '{tagId}'], [$functionId, $tagId], '/functions/{functionId}/tags/{tagId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteTag')
- ->label('description', "Delete a code tag by its unique ID.\n\n")
- ->param('functionId', '' , new Wildcard() , 'Function ID.', false)
- ->param('tagId', '' , new Wildcard() , 'Tag ID.', false)
- ->action(function ( $functionId, $tagId ) use ($parser) {
- /** @var string $functionId */
- /** @var string $tagId */
-
- $client = new Client();
- $path = str_replace(['{functionId}', '{tagId}'], [$functionId, $tagId], '/functions/{functionId}/tags/{tagId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite functions [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "list" => "Get a list of all the project's functions. You can use the query params to filter your results.",
- "create" => "Create a new function. You can pass a list of [permissions](/docs/permissions) to allow different project users or team with access to execute the function using the client API.",
- "listRuntimes" => "Get a list of all runtimes that are currently active in your project.",
- "get" => "Get a function by its unique ID.",
- "update" => "Update function by its unique ID.",
- "delete" => "Delete a function by its unique ID.",
- "listExecutions" => "Get a list of all the current user function execution logs. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's executions. [Learn more about different API modes](/docs/admin).",
- "createExecution" => "Trigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.",
- "getExecution" => "Get a function execution log by its unique ID.",
- "updateTag" => "Update the function code tag ID using the unique function ID. Use this endpoint to switch the code tag that should be executed by the execution endpoint.",
- "listTags" => "Get a list of all the project's code tags. You can use the query params to filter your results.",
- "createTag" => "Create a new function code tag. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's tag to use your new tag UID.
-
-This endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](/docs/functions).
-
-Use the 'command' param to set the entry point used to execute your code.",
- "getTag" => "Get a code tag by its unique ID.",
- "deleteTag" => "Delete a code tag by its unique ID.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite functions COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/health.php b/app/health.php
deleted file mode 100644
index bbfef02..0000000
--- a/app/health.php
+++ /dev/null
@@ -1,231 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite health {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('get')
- ->label('description', "Check the Appwrite HTTP server is up and responsive.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getAntivirus')
- ->label('description', "Check the Appwrite Antivirus server is up and connection is successful.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/anti-virus');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getCache')
- ->label('description', "Check the Appwrite in-memory cache server is up and connection is successful.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/cache');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getDB')
- ->label('description', "Check the Appwrite database server is up and connection is successful.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/db');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getQueueCertificates')
- ->label('description', "Get the number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/queue/certificates');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getQueueFunctions')
- ->label('description', "\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/queue/functions');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getQueueLogs')
- ->label('description', "Get the number of logs that are waiting to be processed in the Appwrite internal queue server.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/queue/logs');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getQueueUsage')
- ->label('description', "Get the number of usage stats that are waiting to be processed in the Appwrite internal queue server.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/queue/usage');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getQueueWebhooks')
- ->label('description', "Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/queue/webhooks');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getStorageLocal')
- ->label('description', "Check the Appwrite local storage device is up and connection is successful.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/storage/local');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getTime')
- ->label('description', "Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/health/time');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite health [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "get" => "Check the Appwrite HTTP server is up and responsive.",
- "getAntivirus" => "Check the Appwrite Antivirus server is up and connection is successful.",
- "getCache" => "Check the Appwrite in-memory cache server is up and connection is successful.",
- "getDB" => "Check the Appwrite database server is up and connection is successful.",
- "getQueueCertificates" => "Get the number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server.",
- "getQueueFunctions" => "",
- "getQueueLogs" => "Get the number of logs that are waiting to be processed in the Appwrite internal queue server.",
- "getQueueUsage" => "Get the number of usage stats that are waiting to be processed in the Appwrite internal queue server.",
- "getQueueWebhooks" => "Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server.",
- "getStorageLocal" => "Check the Appwrite local storage device is up and connection is successful.",
- "getTime" => "Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite health COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/help.php b/app/help.php
deleted file mode 100644
index c94805f..0000000
--- a/app/help.php
+++ /dev/null
@@ -1,36 +0,0 @@
- "The Account service allows you to authenticate and manage a user account.",
- "avatars" => "The Avatars service aims to help you complete everyday tasks related to your app image, icons, and avatars.",
- "database" => "The Database service allows you to create structured collections of documents, query and filter lists of documents",
- "functions" => "The Functions Service allows you view, create and manage your Cloud Functions.",
- "health" => "The Health service allows you to both validate and monitor your Appwrite server's health.",
- "locale" => "The Locale service allows you to customize your app based on your users' location.",
- "storage" => "The Storage service allows you to manage your project files.",
- "teams" => "The Teams service allows you to group users of your project and to enable them to share read and write access to your project resources",
- "users" => "The Users service allows you to manage your project users.",
- "client" => "The Client service allows you to set preferences of your Appwrite CLI",
- "init" => "Init allows you to reset your Appwrite CLI."
- ];
-$parser->formatArray($commands);
-Console::log("\nRun 'appwrite [SERVICE] help' for more information on a service.");
diff --git a/app/init.php b/app/init.php
deleted file mode 100644
index 9b89376..0000000
--- a/app/init.php
+++ /dev/null
@@ -1,196 +0,0 @@
- '',
- 'X-Appwrite-Project' => '',
- 'X-Appwrite-Key' => '',
- 'X-Appwrite-Locale' => '',
-];
-
-
-/**
- * Function to load user preferences from
- * environment variables
- */
-function loadEnvVariables(): bool
-{
- try {
-
- $endpoint = getenv(PREFERENCE_ENDPOINT) ?: '';
- setPreference(PREFERENCE_ENDPOINT, $endpoint);
-
- $project = getenv('X-Appwrite-Project') ?: '';
- setPreference('X-Appwrite-Project', $project);
-
- $key = getenv('X-Appwrite-Key') ?: '';
- setPreference('X-Appwrite-Key', $key);
-
- $locale = getenv('X-Appwrite-Locale') ?: '';
- setPreference('X-Appwrite-Locale', $locale);
-
-
- if (!isPreferenceLoaded()) {
- return false;
- }
-
- $result = savePreferences();
- if ($result === false) {
- return false;
- } else {
- Console::success('✅ Preferences saved successfully');
- }
-
- } catch (Exception $e) {
- return false;
- }
-
- return true;
-}
-
-function isPreferenceLoaded() : bool {
- if(empty(getPreference(PREFERENCE_ENDPOINT))) return false;
- if(empty(getPreference('X-Appwrite-Project'))) return false;
- if(empty(getPreference('X-Appwrite-Key'))) return false;
- if(empty(getPreference('X-Appwrite-Locale'))) return false;
- return true;
-}
-
-/**
- * Function to write user preferences to
- * the JSON file
- *
- * @return int
- */
-function savePreferences(string $filename = USER_PREFERENCES_FILE): int
-{
- global $preferences;
- $jsondata = json_encode($preferences, JSON_PRETTY_PRINT);
- $result = file_put_contents($filename, $jsondata);
- return $result;
-}
-
-function getPreference(string $key): string
-{
- global $preferences;
- return $preferences[$key] ?? '';
-}
-
-function setPreference(string $key , string $value)
-{
- global $preferences;
- $preferences[$key] = $value;
-}
-
-function promptUser()
-{
- Console::info("🟢 Starting prompt\n");
-
- if(empty(getPreference(PREFERENCE_ENDPOINT))) {
- $endpoint = Console::confirm('🟢 Choose your API Endpoint: ( default: http://localhost/v1 )');
- setPreference(PREFERENCE_ENDPOINT, empty($endpoint) ? 'http://localhost/v1' : $endpoint);
- }
-
- if(empty(getPreference('X-Appwrite-Project'))) {
- $project = Console::confirm('🟢 Enter your project from the Appwrite console: ');
- if (empty($project)) {
- Console::error("❌ You cannot continue without a project. Exiting...");
- exit();
- }
- setPreference('X-Appwrite-Project', $project);
- }
-
- if(empty(getPreference('X-Appwrite-Key'))) {
- $key = Console::confirm('🟢 Enter your key from the Appwrite console: ');
- if (empty($key)) {
- Console::error("❌ You cannot continue without a key. Exiting...");
- exit();
- }
- setPreference('X-Appwrite-Key', $key);
- }
-
- if(empty(getPreference('X-Appwrite-Locale'))) {
- $locale = Console::confirm('🟢 Enter your locale: : ( default: en-US )');
- setPreference('X-Appwrite-Locale', empty($locale) ? 'en-US' : $locale );
- }
-
- $result = savePreferences();
- if ($result === false) {
- throw new Exception('❌ Could not save preferences.');
- } else {
- Console::success('✅ Preferences saved successfully');
- }
-}
-
-$cli = new CLI();
-$parser = new Parser();
-
-$cli->
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('init')
- ->label('description', "The init command is used to initialize your CLI\n")
- ->param('endpoint', '', new Wildcard(), 'Your Appwrite endpoint', true)
- ->param('project', '', new Wildcard(), 'Your project ID', true)
- ->param('key', '', new Wildcard(), 'Your secret API key', true)
- ->param('locale', '', new Wildcard(), '', true)
- ->action(function( $endpoint, $project, $key, $locale ) {
- /*
- * Check if environment variables exist
- * Else prompt the user
- */
-
- putenv("endpoint=$endpoint");
- putenv("X-Appwrite-Project=$project");
- putenv("X-Appwrite-Key=$key");
- putenv("X-Appwrite-Locale=$locale");
-
- if (!loadEnvVariables()) {
- promptUser();
- }
-});
-
-$cli->run();
diff --git a/app/locale.php b/app/locale.php
deleted file mode 100644
index a8b32c4..0000000
--- a/app/locale.php
+++ /dev/null
@@ -1,175 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite locale {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('get')
- ->label('description', "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.
-
-([IP Geolocation by DB-IP](https://db-ip.com))\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getContinents')
- ->label('description', "List of all continents. You can use the locale header to get the data in a supported language.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale/continents');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getCountries')
- ->label('description', "List of all countries. You can use the locale header to get the data in a supported language.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale/countries');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getCountriesEU')
- ->label('description', "List of all countries that are currently members of the EU. You can use the locale header to get the data in a supported language.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale/countries/eu');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getCountriesPhones')
- ->label('description', "List of all countries phone codes. You can use the locale header to get the data in a supported language.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale/countries/phones');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getCurrencies')
- ->label('description', "List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in a supported language.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale/currencies');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getLanguages')
- ->label('description', "List of all languages classified by ISO 639-1 including 2-letter code, name in English, and name in the respective language.\n\n")
- ->action(function ( ) use ($parser) {
-
- $client = new Client();
- $path = str_replace([], [], '/locale/languages');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite locale [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "get" => "Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language.
-
-([IP Geolocation by DB-IP](https://db-ip.com))",
- "getContinents" => "List of all continents. You can use the locale header to get the data in a supported language.",
- "getCountries" => "List of all countries. You can use the locale header to get the data in a supported language.",
- "getCountriesEU" => "List of all countries that are currently members of the EU. You can use the locale header to get the data in a supported language.",
- "getCountriesPhones" => "List of all countries phone codes. You can use the locale header to get the data in a supported language.",
- "getCurrencies" => "List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in a supported language.",
- "getLanguages" => "List of all languages classified by ISO 639-1 including 2-letter code, name in English, and name in the respective language.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite locale COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/storage.php b/app/storage.php
deleted file mode 100644
index ed6bde8..0000000
--- a/app/storage.php
+++ /dev/null
@@ -1,276 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite storage {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('listFiles')
- ->label('description', "Get a list of all the user files. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's files. [Learn more about different API modes](/docs/admin).\n\n")
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of files to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the file used as the starting point for the query, excluding the file itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace([], [], '/storage/files');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createFile')
- ->label('description', "Create a new file. The user who creates the file will automatically be assigned to read and write access unless he has passed custom values for read and write arguments.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.', false)
- ->param('file', '' , new Wildcard() , 'Binary file.', false)
- ->param('read', [] , new Wildcard() , 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->param('write', [] , new Wildcard() , 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
- ->action(function ( $fileId, $file, $read, $write ) use ($parser) {
- /** @var string $fileId */
- /** @var file $file */
- /** @var array $read */
- /** @var array $write */
-
- $client = new Client();
- $path = str_replace([], [], '/storage/files');
- $params = [];
- /** Body Params */
- $params['fileId'] = $fileId;
- $file = realpath(__DIR__.'/../files/'.\urldecode($file));
- if (file_exists($file) === false ) {
- throw new Exception("Path doesn't exist. Please ensure that the path is within the current directory. ");
- }
- $cFile = new \CURLFile($file, 'image/png' , basename($file));
- $params['file'] = $cFile;
- $params['read'] = !is_array($read) ? array($read) : $read;
- $params['write'] = !is_array($write) ? array($write) : $write;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'multipart/form-data',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getFile')
- ->label('description', "Get a file by its unique ID. This endpoint response returns a JSON object with the file metadata.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID.', false)
- ->action(function ( $fileId ) use ($parser) {
- /** @var string $fileId */
-
- $client = new Client();
- $path = str_replace(['{fileId}'], [$fileId], '/storage/files/{fileId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateFile')
- ->label('description', "Update a file by its unique ID. Only users with write permissions have access to update this resource.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID.', false)
- ->param('read', '' , new Wildcard() , 'An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->param('write', '' , new Wildcard() , 'An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', false)
- ->action(function ( $fileId, $read, $write ) use ($parser) {
- /** @var string $fileId */
- /** @var array $read */
- /** @var array $write */
-
- $client = new Client();
- $path = str_replace(['{fileId}'], [$fileId], '/storage/files/{fileId}');
- $params = [];
- /** Body Params */
- $params['read'] = !is_array($read) ? array($read) : $read;
- $params['write'] = !is_array($write) ? array($write) : $write;
- $response = $client->call(Client::METHOD_PUT, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteFile')
- ->label('description', "Delete a file by its unique ID. Only users with write permissions have access to delete this resource.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID.', false)
- ->action(function ( $fileId ) use ($parser) {
- /** @var string $fileId */
-
- $client = new Client();
- $path = str_replace(['{fileId}'], [$fileId], '/storage/files/{fileId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getFileDownload')
- ->label('description', "Get a file content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID.', false)
- ->action(function ( $fileId ) use ($parser) {
- /** @var string $fileId */
-
- $client = new Client();
- $path = str_replace(['{fileId}'], [$fileId], '/storage/files/{fileId}/download');
- $params = [];
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getFilePreview')
- ->label('description', "Get a file preview image. Currently, this method supports preview for image files (jpg, png, and gif), other supported formats, like pdf, docs, slides, and spreadsheets, will return the file icon image. You can also pass query string arguments for cutting and resizing your preview image.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID.', false)
- ->param('width', 0 , new Wildcard() , 'Resize preview image width, Pass an integer between 0 to 4000.', true)
- ->param('height', 0 , new Wildcard() , 'Resize preview image height, Pass an integer between 0 to 4000.', true)
- ->param('gravity', 'center' , new Wildcard() , 'Image crop gravity. Can be one of center,top-left,top,top-right,left,right,bottom-left,bottom,bottom-right', true)
- ->param('quality', 100 , new Wildcard() , 'Preview image quality. Pass an integer between 0 to 100. Defaults to 100.', true)
- ->param('borderWidth', 0 , new Wildcard() , 'Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0.', true)
- ->param('borderColor', '' , new Wildcard() , 'Preview image border color. Use a valid HEX color, no # is needed for prefix.', true)
- ->param('borderRadius', 0 , new Wildcard() , 'Preview image border radius in pixels. Pass an integer between 0 to 4000.', true)
- ->param('opacity', 1 , new Wildcard() , 'Preview image opacity. Only works with images having an alpha channel (like png). Pass a number between 0 to 1.', true)
- ->param('rotation', 0 , new Wildcard() , 'Preview image rotation in degrees. Pass an integer between -360 and 360.', true)
- ->param('background', '' , new Wildcard() , 'Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.', true)
- ->param('output', '' , new Wildcard() , 'Output format type (jpeg, jpg, png, gif and webp).', true)
- ->action(function ( $fileId, $width, $height, $gravity, $quality, $borderWidth, $borderColor, $borderRadius, $opacity, $rotation, $background, $output ) use ($parser) {
- /** @var string $fileId */
- /** @var integer $width */
- /** @var integer $height */
- /** @var string $gravity */
- /** @var integer $quality */
- /** @var integer $borderWidth */
- /** @var string $borderColor */
- /** @var integer $borderRadius */
- /** @var number $opacity */
- /** @var integer $rotation */
- /** @var string $background */
- /** @var string $output */
-
- $client = new Client();
- $path = str_replace(['{fileId}'], [$fileId], '/storage/files/{fileId}/preview');
- $params = [];
- /** Query Params */
- $params['width'] = $width;
- $params['height'] = $height;
- $params['gravity'] = $gravity;
- $params['quality'] = $quality;
- $params['borderWidth'] = $borderWidth;
- $params['borderColor'] = $borderColor;
- $params['borderRadius'] = $borderRadius;
- $params['opacity'] = $opacity;
- $params['rotation'] = $rotation;
- $params['background'] = $background;
- $params['output'] = $output;
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-$cli
- ->task('getFileView')
- ->label('description', "Get a file content by its unique ID. This endpoint is similar to the download method but returns with no 'Content-Disposition: attachment' header.\n\n")
- ->param('fileId', '' , new Wildcard() , 'File ID.', false)
- ->action(function ( $fileId ) use ($parser) {
- /** @var string $fileId */
-
- $client = new Client();
- $path = str_replace(['{fileId}'], [$fileId], '/storage/files/{fileId}/view');
- $params = [];
- $params['project'] = $client->getPreference('X-Appwrite-Project');
- $params['key'] = $client->getPreference('X-Appwrite-Key');
- $path = $client->getPreference(Client::PREFERENCE_ENDPOINT).$path . "?" . http_build_query($params);
- Console::success($path);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite storage [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "listFiles" => "Get a list of all the user files. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's files. [Learn more about different API modes](/docs/admin).",
- "createFile" => "Create a new file. The user who creates the file will automatically be assigned to read and write access unless he has passed custom values for read and write arguments.",
- "getFile" => "Get a file by its unique ID. This endpoint response returns a JSON object with the file metadata.",
- "updateFile" => "Update a file by its unique ID. Only users with write permissions have access to update this resource.",
- "deleteFile" => "Delete a file by its unique ID. Only users with write permissions have access to delete this resource.",
- "getFileDownload" => "Get a file content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory.",
- "getFilePreview" => "Get a file preview image. Currently, this method supports preview for image files (jpg, png, and gif), other supported formats, like pdf, docs, slides, and spreadsheets, will return the file icon image. You can also pass query string arguments for cutting and resizing your preview image.",
- "getFileView" => "Get a file content by its unique ID. This endpoint is similar to the download method but returns with no 'Content-Disposition: attachment' header.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite storage COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/teams.php b/app/teams.php
deleted file mode 100644
index 41ac952..0000000
--- a/app/teams.php
+++ /dev/null
@@ -1,345 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite teams {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('list')
- ->label('description', "Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results.
-
-In admin mode, this endpoint returns a list of all the teams in the current project. [Learn more about different API modes](/docs/admin).\n\n")
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of teams to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the team used as the starting point for the query, excluding the team itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace([], [], '/teams');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('create')
- ->label('description', "Create a new team. The user who creates the team will automatically be assigned as the owner of the team. Only the users with the owner role can invite new members, add new owners and delete or update the team.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.', false)
- ->param('name', '' , new Wildcard() , 'Team name. Max length: 128 chars.', false)
- ->param('roles', ["owner"] , new Wildcard() , 'Array of strings. Use this param to set the roles in the team for the user who created it. The default role is **owner**. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.', true)
- ->action(function ( $teamId, $name, $roles ) use ($parser) {
- /** @var string $teamId */
- /** @var string $name */
- /** @var array $roles */
-
- $client = new Client();
- $path = str_replace([], [], '/teams');
- $params = [];
- /** Body Params */
- $params['teamId'] = $teamId;
- $params['name'] = $name;
- $params['roles'] = !is_array($roles) ? array($roles) : $roles;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('get')
- ->label('description', "Get a team by its ID. All team members have read access for this resource.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->action(function ( $teamId ) use ($parser) {
- /** @var string $teamId */
-
- $client = new Client();
- $path = str_replace(['{teamId}'], [$teamId], '/teams/{teamId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('update')
- ->label('description', "Update a team using its ID. Only members with the owner role can update the team.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('name', '' , new Wildcard() , 'New team name. Max length: 128 chars.', false)
- ->action(function ( $teamId, $name ) use ($parser) {
- /** @var string $teamId */
- /** @var string $name */
-
- $client = new Client();
- $path = str_replace(['{teamId}'], [$teamId], '/teams/{teamId}');
- $params = [];
- /** Body Params */
- $params['name'] = $name;
- $response = $client->call(Client::METHOD_PUT, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('delete')
- ->label('description', "Delete a team using its ID. Only team members with the owner role can delete the team.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->action(function ( $teamId ) use ($parser) {
- /** @var string $teamId */
-
- $client = new Client();
- $path = str_replace(['{teamId}'], [$teamId], '/teams/{teamId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getMemberships')
- ->label('description', "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of memberships to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the membership used as the starting point for the query, excluding the membership itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $teamId, $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $teamId */
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace(['{teamId}'], [$teamId], '/teams/{teamId}/memberships');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('createMembership')
- ->label('description', "Invite a new member to join your team. If initiated from the client SDK, an email with a link to join the team will be sent to the member's email address and an account will be created for them should they not be signed up already. If initiated from server-side SDKs, the new member will automatically be added to the team.
-
-Use the 'url' parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the [Update Team Membership Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow the user to accept the invitation to the team.
-
-Please note that to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when adding your platforms in the console interface.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('email', '' , new Wildcard() , 'Email of the new team member.', false)
- ->param('roles', '' , new Wildcard() , 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](/docs/permissions). Max length for each role is 32 chars.', false)
- ->param('url', '' , new Wildcard() , 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', false)
- ->param('name', '' , new Wildcard() , 'Name of the new team member. Max length: 128 chars.', true)
- ->action(function ( $teamId, $email, $roles, $url, $name ) use ($parser) {
- /** @var string $teamId */
- /** @var string $email */
- /** @var array $roles */
- /** @var string $url */
- /** @var string $name */
-
- $client = new Client();
- $path = str_replace(['{teamId}'], [$teamId], '/teams/{teamId}/memberships');
- $params = [];
- /** Body Params */
- $params['email'] = $email;
- $params['roles'] = !is_array($roles) ? array($roles) : $roles;
- $params['url'] = $url;
- $params['name'] = $name;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getMembership')
- ->label('description', "Get a team member by the membership unique id. All team members have read access for this resource.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('membershipId', '' , new Wildcard() , 'Membership ID.', false)
- ->action(function ( $teamId, $membershipId ) use ($parser) {
- /** @var string $teamId */
- /** @var string $membershipId */
-
- $client = new Client();
- $path = str_replace(['{teamId}', '{membershipId}'], [$teamId, $membershipId], '/teams/{teamId}/memberships/{membershipId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateMembershipRoles')
- ->label('description', "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](/docs/permissions).\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('membershipId', '' , new Wildcard() , 'Membership ID.', false)
- ->param('roles', '' , new Wildcard() , 'An array of strings. Use this param to set the user's roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Max length for each role is 32 chars.', false)
- ->action(function ( $teamId, $membershipId, $roles ) use ($parser) {
- /** @var string $teamId */
- /** @var string $membershipId */
- /** @var array $roles */
-
- $client = new Client();
- $path = str_replace(['{teamId}', '{membershipId}'], [$teamId, $membershipId], '/teams/{teamId}/memberships/{membershipId}');
- $params = [];
- /** Body Params */
- $params['roles'] = !is_array($roles) ? array($roles) : $roles;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteMembership')
- ->label('description', "This endpoint allows a user to leave a team or for a team owner to delete the membership of any other team member. You can also use this endpoint to delete a user membership even if it is not accepted.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('membershipId', '' , new Wildcard() , 'Membership ID.', false)
- ->action(function ( $teamId, $membershipId ) use ($parser) {
- /** @var string $teamId */
- /** @var string $membershipId */
-
- $client = new Client();
- $path = str_replace(['{teamId}', '{membershipId}'], [$teamId, $membershipId], '/teams/{teamId}/memberships/{membershipId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateMembershipStatus')
- ->label('description', "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.\n\n")
- ->param('teamId', '' , new Wildcard() , 'Team ID.', false)
- ->param('membershipId', '' , new Wildcard() , 'Membership ID.', false)
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('secret', '' , new Wildcard() , 'Secret key.', false)
- ->action(function ( $teamId, $membershipId, $userId, $secret ) use ($parser) {
- /** @var string $teamId */
- /** @var string $membershipId */
- /** @var string $userId */
- /** @var string $secret */
-
- $client = new Client();
- $path = str_replace(['{teamId}', '{membershipId}'], [$teamId, $membershipId], '/teams/{teamId}/memberships/{membershipId}/status');
- $params = [];
- /** Body Params */
- $params['userId'] = $userId;
- $params['secret'] = $secret;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite teams [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "list" => "Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results.
-
-In admin mode, this endpoint returns a list of all the teams in the current project. [Learn more about different API modes](/docs/admin).",
- "create" => "Create a new team. The user who creates the team will automatically be assigned as the owner of the team. Only the users with the owner role can invite new members, add new owners and delete or update the team.",
- "get" => "Get a team by its ID. All team members have read access for this resource.",
- "update" => "Update a team using its ID. Only members with the owner role can update the team.",
- "delete" => "Delete a team using its ID. Only team members with the owner role can delete the team.",
- "getMemberships" => "Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.",
- "createMembership" => "Invite a new member to join your team. If initiated from the client SDK, an email with a link to join the team will be sent to the member's email address and an account will be created for them should they not be signed up already. If initiated from server-side SDKs, the new member will automatically be added to the team.
-
-Use the 'url' parameter to redirect the user from the invitation email back to your app. When the user is redirected, use the [Update Team Membership Status](/docs/client/teams#teamsUpdateMembershipStatus) endpoint to allow the user to accept the invitation to the team.
-
-Please note that to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URL's are the once from domains you have set when adding your platforms in the console interface.",
- "getMembership" => "Get a team member by the membership unique id. All team members have read access for this resource.",
- "updateMembershipRoles" => "Modify the roles of a team member. Only team members with the owner role have access to this endpoint. Learn more about [roles and permissions](/docs/permissions).",
- "deleteMembership" => "This endpoint allows a user to leave a team or for a team owner to delete the membership of any other team member. You can also use this endpoint to delete a user membership even if it is not accepted.",
- "updateMembershipStatus" => "Use this endpoint to allow a user to accept an invitation to join a team after being redirected back to your app from the invitation email received by the user.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite teams COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/app/users.php b/app/users.php
deleted file mode 100644
index 7caa667..0000000
--- a/app/users.php
+++ /dev/null
@@ -1,382 +0,0 @@
-
- init(function() use ($cli, $parser) {
-
- if (array_key_exists('help', $cli->getArgs())) {
- $taskName = $cli->match()->getName();
- $task = $cli->getTasks()[$taskName];
- $description = $task->getLabel('description', '');
- $params = $task->getParams();
-
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m") ;
- Console::log("\nUsage : appwrite users {$taskName} --[OPTIONS] \n");
- Console::log($description);
- Console::log("Options:");
- array_walk($params, function(&$key) {
- $key = $key['description'];
- });
- $parser->formatArray($params);
- Console::exit(0);
- }
- });
-
-$cli
- ->task('list')
- ->label('description', "Get a list of all the project's users. You can use the query params to filter your results.\n\n")
- ->param('search', '' , new Wildcard() , 'Search term to filter your list results. Max length: 256 chars.', true)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of users to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursor', '' , new Wildcard() , 'ID of the user used as the starting point for the query, excluding the user itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->param('cursorDirection', 'after' , new Wildcard() , 'Direction of the cursor.', true)
- ->param('orderType', 'ASC' , new Wildcard() , 'Order result by ASC or DESC order.', true)
- ->action(function ( $search, $limit, $offset, $cursor, $cursorDirection, $orderType ) use ($parser) {
- /** @var string $search */
- /** @var integer $limit */
- /** @var integer $offset */
- /** @var string $cursor */
- /** @var string $cursorDirection */
- /** @var string $orderType */
-
- $client = new Client();
- $path = str_replace([], [], '/users');
- $params = [];
- /** Query Params */
- $params['search'] = $search;
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $params['cursor'] = $cursor;
- $params['cursorDirection'] = $cursorDirection;
- $params['orderType'] = $orderType;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('create')
- ->label('description', "Create a new user.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID. Choose your own unique ID or pass the string `unique()` to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.', false)
- ->param('email', '' , new Wildcard() , 'User email.', false)
- ->param('password', '' , new Wildcard() , 'User password. Must be at least 8 chars.', false)
- ->param('name', '' , new Wildcard() , 'User name. Max length: 128 chars.', true)
- ->action(function ( $userId, $email, $password, $name ) use ($parser) {
- /** @var string $userId */
- /** @var string $email */
- /** @var string $password */
- /** @var string $name */
-
- $client = new Client();
- $path = str_replace([], [], '/users');
- $params = [];
- /** Body Params */
- $params['userId'] = $userId;
- $params['email'] = $email;
- $params['password'] = $password;
- $params['name'] = $name;
- $response = $client->call(Client::METHOD_POST, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('get')
- ->label('description', "Get a user by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->action(function ( $userId ) use ($parser) {
- /** @var string $userId */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('delete')
- ->label('description', "Delete a user by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->action(function ( $userId ) use ($parser) {
- /** @var string $userId */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateEmail')
- ->label('description', "Update the user email by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('email', '' , new Wildcard() , 'User email.', false)
- ->action(function ( $userId, $email ) use ($parser) {
- /** @var string $userId */
- /** @var string $email */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/email');
- $params = [];
- /** Body Params */
- $params['email'] = $email;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getLogs')
- ->label('description', "Get the user activity logs list by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('limit', 25 , new Wildcard() , 'Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
- ->param('offset', 0 , new Wildcard() , 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
- ->action(function ( $userId, $limit, $offset ) use ($parser) {
- /** @var string $userId */
- /** @var integer $limit */
- /** @var integer $offset */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/logs');
- $params = [];
- /** Query Params */
- $params['limit'] = $limit;
- $params['offset'] = $offset;
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateName')
- ->label('description', "Update the user name by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('name', '' , new Wildcard() , 'User name. Max length: 128 chars.', false)
- ->action(function ( $userId, $name ) use ($parser) {
- /** @var string $userId */
- /** @var string $name */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/name');
- $params = [];
- /** Body Params */
- $params['name'] = $name;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updatePassword')
- ->label('description', "Update the user password by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('password', '' , new Wildcard() , 'New user password. Must be at least 8 chars.', false)
- ->action(function ( $userId, $password ) use ($parser) {
- /** @var string $userId */
- /** @var string $password */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/password');
- $params = [];
- /** Body Params */
- $params['password'] = $password;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getPrefs')
- ->label('description', "Get the user preferences by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->action(function ( $userId ) use ($parser) {
- /** @var string $userId */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/prefs');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updatePrefs')
- ->label('description', "Update the user preferences by its unique ID. You can pass only the specific settings you wish to update.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('prefs', '' , new Wildcard() , 'Prefs key-value JSON object.', false)
- ->action(function ( $userId, $prefs ) use ($parser) {
- /** @var string $userId */
- /** @var object $prefs */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/prefs');
- $params = [];
- /** Body Params */
- $params['prefs'] = \json_decode($prefs);
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('getSessions')
- ->label('description', "Get the user sessions list by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->action(function ( $userId ) use ($parser) {
- /** @var string $userId */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/sessions');
- $params = [];
- $response = $client->call(Client::METHOD_GET, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteSessions')
- ->label('description', "Delete all user's sessions by using the user's unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->action(function ( $userId ) use ($parser) {
- /** @var string $userId */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/sessions');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('deleteSession')
- ->label('description', "Delete a user sessions by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('sessionId', '' , new Wildcard() , 'Session ID.', false)
- ->action(function ( $userId, $sessionId ) use ($parser) {
- /** @var string $userId */
- /** @var string $sessionId */
-
- $client = new Client();
- $path = str_replace(['{userId}', '{sessionId}'], [$userId, $sessionId], '/users/{userId}/sessions/{sessionId}');
- $params = [];
- $response = $client->call(Client::METHOD_DELETE, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateStatus')
- ->label('description', "Update the user status by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('status', '' , new Wildcard() , 'User Status. To activate the user pass `true` and to block the user pass `false`.', false)
- ->action(function ( $userId, $status ) use ($parser) {
- /** @var string $userId */
- /** @var boolean $status */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/status');
- $params = [];
- /** Body Params */
- $params['status'] = $status;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-$cli
- ->task('updateVerification')
- ->label('description', "Update the user email verification status by its unique ID.\n\n")
- ->param('userId', '' , new Wildcard() , 'User ID.', false)
- ->param('emailVerification', '' , new Wildcard() , 'User email verification status.', false)
- ->action(function ( $userId, $emailVerification ) use ($parser) {
- /** @var string $userId */
- /** @var boolean $emailVerification */
-
- $client = new Client();
- $path = str_replace(['{userId}'], [$userId], '/users/{userId}/verification');
- $params = [];
- /** Body Params */
- $params['emailVerification'] = $emailVerification;
- $response = $client->call(Client::METHOD_PATCH, $path, [
- 'content-type' => 'application/json',
- ], $params);
- $parser->parseResponse($response);
- });
-
-
-$cli
- ->task('help')
- ->action(function() use ($parser) {
- Console::log("\e[0;31;m
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
- \e[0m");
- Console::log("\nUsage : appwrite users [COMMAND]\n");
- Console::log("Commands :");
- $commands = [
- "list" => "Get a list of all the project's users. You can use the query params to filter your results.",
- "create" => "Create a new user.",
- "get" => "Get a user by its unique ID.",
- "delete" => "Delete a user by its unique ID.",
- "updateEmail" => "Update the user email by its unique ID.",
- "getLogs" => "Get the user activity logs list by its unique ID.",
- "updateName" => "Update the user name by its unique ID.",
- "updatePassword" => "Update the user password by its unique ID.",
- "getPrefs" => "Get the user preferences by its unique ID.",
- "updatePrefs" => "Update the user preferences by its unique ID. You can pass only the specific settings you wish to update.",
- "getSessions" => "Get the user sessions list by its unique ID.",
- "deleteSessions" => "Delete all user's sessions by using the user's unique ID.",
- "deleteSession" => "Delete a user sessions by its unique ID.",
- "updateStatus" => "Update the user status by its unique ID.",
- "updateVerification" => "Update the user email verification status by its unique ID.",
- ];
- $parser->formatArray($commands);
- Console::log("\nRun 'appwrite users COMMAND --help' for more information on a command.");
- });
-
-
-$cli->run();
diff --git a/bin/account b/bin/account
deleted file mode 100644
index 1510ef0..0000000
--- a/bin/account
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/account.php help
-else
- php /usr/local/code/app/account.php $@
-fi
\ No newline at end of file
diff --git a/bin/avatars b/bin/avatars
deleted file mode 100644
index 54f267b..0000000
--- a/bin/avatars
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/avatars.php help
-else
- php /usr/local/code/app/avatars.php $@
-fi
\ No newline at end of file
diff --git a/bin/client b/bin/client
deleted file mode 100644
index 5f69306..0000000
--- a/bin/client
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/client.php help
-else
- php /usr/local/code/app/client.php $@
-fi
\ No newline at end of file
diff --git a/bin/database b/bin/database
deleted file mode 100644
index 6f4bbb9..0000000
--- a/bin/database
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/database.php help
-else
- php /usr/local/code/app/database.php $@
-fi
\ No newline at end of file
diff --git a/bin/functions b/bin/functions
deleted file mode 100644
index 8005325..0000000
--- a/bin/functions
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/functions.php help
-else
- php /usr/local/code/app/functions.php $@
-fi
\ No newline at end of file
diff --git a/bin/health b/bin/health
deleted file mode 100644
index a935e28..0000000
--- a/bin/health
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/health.php help
-else
- php /usr/local/code/app/health.php $@
-fi
\ No newline at end of file
diff --git a/bin/help b/bin/help
deleted file mode 100644
index 7e963e3..0000000
--- a/bin/help
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-php /usr/local/code/app/help.php $@
\ No newline at end of file
diff --git a/bin/init b/bin/init
deleted file mode 100644
index 0495b98..0000000
--- a/bin/init
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-php /usr/local/code/app/init.php init $@
\ No newline at end of file
diff --git a/bin/locale b/bin/locale
deleted file mode 100644
index 8ad1ad5..0000000
--- a/bin/locale
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/locale.php help
-else
- php /usr/local/code/app/locale.php $@
-fi
\ No newline at end of file
diff --git a/bin/storage b/bin/storage
deleted file mode 100644
index ac737ec..0000000
--- a/bin/storage
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/storage.php help
-else
- php /usr/local/code/app/storage.php $@
-fi
\ No newline at end of file
diff --git a/bin/teams b/bin/teams
deleted file mode 100644
index dd44bf3..0000000
--- a/bin/teams
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/teams.php help
-else
- php /usr/local/code/app/teams.php $@
-fi
\ No newline at end of file
diff --git a/bin/users b/bin/users
deleted file mode 100644
index 460ab4c..0000000
--- a/bin/users
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-if [[ $# -eq 0 ]]; then
- php /usr/local/code/app/users.php help
-else
- php /usr/local/code/app/users.php $@
-fi
\ No newline at end of file
diff --git a/bin/version b/bin/version
deleted file mode 100644
index 494bd0f..0000000
--- a/bin/version
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-php /usr/local/code/app/client.php version
\ No newline at end of file
diff --git a/composer.json b/composer.json
deleted file mode 100644
index 62f6026..0000000
--- a/composer.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "appwrite/cli",
- "description": "Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API",
- "type": "library",
- "license": "BSD-3-Clause",
- "support": {
- "url": "https://appwrite.io/support",
- "email": "team@appwrite.io"
- },
- "autoload": {
- "psr-4": {
- "Appwrite\\": "src/"
- }
- },
- "require": {
- "php": ">=7.4.0",
- "utopia-php/cli": "0.11.0",
- "jc21/clitable": "^1.2"
- },
- "minimum-stability": "dev"
-}
\ No newline at end of file
diff --git a/docs/examples/account/create-anonymous-session.md b/docs/examples/account/create-anonymous-session.md
new file mode 100644
index 0000000..a7eb9c5
--- /dev/null
+++ b/docs/examples/account/create-anonymous-session.md
@@ -0,0 +1 @@
+appwrite account createAnonymousSession
diff --git a/docs/examples/account/create-j-w-t.md b/docs/examples/account/create-j-w-t.md
new file mode 100644
index 0000000..7b53379
--- /dev/null
+++ b/docs/examples/account/create-j-w-t.md
@@ -0,0 +1 @@
+appwrite account createJWT
diff --git a/docs/examples/account/create-magic-u-r-l-session.md b/docs/examples/account/create-magic-u-r-l-session.md
new file mode 100644
index 0000000..0060f2a
--- /dev/null
+++ b/docs/examples/account/create-magic-u-r-l-session.md
@@ -0,0 +1,4 @@
+appwrite account createMagicURLSession \
+ --userId [USER_ID] \
+ --email email@example.com \
+
diff --git a/docs/examples/account/create-o-auth2session.md b/docs/examples/account/create-o-auth2session.md
new file mode 100644
index 0000000..9159b8f
--- /dev/null
+++ b/docs/examples/account/create-o-auth2session.md
@@ -0,0 +1,5 @@
+appwrite account createOAuth2Session \
+ --provider amazon \
+
+
+
diff --git a/docs/examples/account/create-recovery.md b/docs/examples/account/create-recovery.md
index f35a433..ea8c145 100644
--- a/docs/examples/account/create-recovery.md
+++ b/docs/examples/account/create-recovery.md
@@ -1,3 +1,3 @@
appwrite account createRecovery \
- --email="email@example.com" \
- --url="https://example.com"
+ --email email@example.com \
+ --url https://example.com
diff --git a/docs/examples/account/create-session.md b/docs/examples/account/create-session.md
new file mode 100644
index 0000000..e174029
--- /dev/null
+++ b/docs/examples/account/create-session.md
@@ -0,0 +1,3 @@
+appwrite account createSession \
+ --email email@example.com \
+ --password password
diff --git a/docs/examples/account/create-verification.md b/docs/examples/account/create-verification.md
index d3c8955..402038b 100644
--- a/docs/examples/account/create-verification.md
+++ b/docs/examples/account/create-verification.md
@@ -1,2 +1,2 @@
appwrite account createVerification \
- --url="https://example.com"
+ --url https://example.com
diff --git a/docs/examples/account/create.md b/docs/examples/account/create.md
new file mode 100644
index 0000000..7d2221b
--- /dev/null
+++ b/docs/examples/account/create.md
@@ -0,0 +1,5 @@
+appwrite account create \
+ --userId [USER_ID] \
+ --email email@example.com \
+ --password password \
+
diff --git a/docs/examples/account/delete-session.md b/docs/examples/account/delete-session.md
index f615bbb..2c68c1a 100644
--- a/docs/examples/account/delete-session.md
+++ b/docs/examples/account/delete-session.md
@@ -1,2 +1,2 @@
appwrite account deleteSession \
- --sessionId="[SESSION_ID]"
+ --sessionId [SESSION_ID]
diff --git a/docs/examples/account/get-logs.md b/docs/examples/account/get-logs.md
index 2bb6de8..9ab3150 100644
--- a/docs/examples/account/get-logs.md
+++ b/docs/examples/account/get-logs.md
@@ -1,3 +1,3 @@
appwrite account getLogs \
- --limit="0" \
- --offset="0"
+
+
diff --git a/docs/examples/account/get-session.md b/docs/examples/account/get-session.md
index 0b5a4f2..fac3fca 100644
--- a/docs/examples/account/get-session.md
+++ b/docs/examples/account/get-session.md
@@ -1,2 +1,2 @@
appwrite account getSession \
- --sessionId="[SESSION_ID]"
+ --sessionId [SESSION_ID]
diff --git a/docs/examples/account/update-email.md b/docs/examples/account/update-email.md
index 9c27324..81938ff 100644
--- a/docs/examples/account/update-email.md
+++ b/docs/examples/account/update-email.md
@@ -1,3 +1,3 @@
appwrite account updateEmail \
- --email="email@example.com" \
- --password="password"
+ --email email@example.com \
+ --password password
diff --git a/docs/examples/account/update-magic-u-r-l-session.md b/docs/examples/account/update-magic-u-r-l-session.md
new file mode 100644
index 0000000..1411370
--- /dev/null
+++ b/docs/examples/account/update-magic-u-r-l-session.md
@@ -0,0 +1,3 @@
+appwrite account updateMagicURLSession \
+ --userId [USER_ID] \
+ --secret [SECRET]
diff --git a/docs/examples/account/update-name.md b/docs/examples/account/update-name.md
index 64890ae..f4acb58 100644
--- a/docs/examples/account/update-name.md
+++ b/docs/examples/account/update-name.md
@@ -1,2 +1,2 @@
appwrite account updateName \
- --name="[NAME]"
+ --name [NAME]
diff --git a/docs/examples/account/update-password.md b/docs/examples/account/update-password.md
index 51ebdd4..520f9bb 100644
--- a/docs/examples/account/update-password.md
+++ b/docs/examples/account/update-password.md
@@ -1,3 +1,3 @@
appwrite account updatePassword \
- --password="password" \
- --oldPassword="password"
+ --password password \
+
diff --git a/docs/examples/account/update-prefs.md b/docs/examples/account/update-prefs.md
index acc0e8e..568ac66 100644
--- a/docs/examples/account/update-prefs.md
+++ b/docs/examples/account/update-prefs.md
@@ -1,2 +1,2 @@
appwrite account updatePrefs \
- --prefs="{}"
+ --prefs '{ "key": "value" }'
diff --git a/docs/examples/account/update-recovery.md b/docs/examples/account/update-recovery.md
index 04f09b9..7825aac 100644
--- a/docs/examples/account/update-recovery.md
+++ b/docs/examples/account/update-recovery.md
@@ -1,5 +1,5 @@
appwrite account updateRecovery \
- --userId="[USER_ID]" \
- --secret="[SECRET]" \
- --password="password" \
- --passwordAgain="password"
+ --userId [USER_ID] \
+ --secret [SECRET] \
+ --password password \
+ --passwordAgain password
diff --git a/docs/examples/account/update-session.md b/docs/examples/account/update-session.md
new file mode 100644
index 0000000..56f7456
--- /dev/null
+++ b/docs/examples/account/update-session.md
@@ -0,0 +1,2 @@
+appwrite account updateSession \
+ --sessionId [SESSION_ID]
diff --git a/docs/examples/account/update-verification.md b/docs/examples/account/update-verification.md
index 2315619..ff420b5 100644
--- a/docs/examples/account/update-verification.md
+++ b/docs/examples/account/update-verification.md
@@ -1,3 +1,3 @@
appwrite account updateVerification \
- --userId="[USER_ID]" \
- --secret="[SECRET]"
+ --userId [USER_ID] \
+ --secret [SECRET]
diff --git a/docs/examples/avatars/get-browser.md b/docs/examples/avatars/get-browser.md
index d2d0f28..6b4f0b8 100644
--- a/docs/examples/avatars/get-browser.md
+++ b/docs/examples/avatars/get-browser.md
@@ -1,5 +1,5 @@
appwrite avatars getBrowser \
- --code="aa" \
- --width="0" \
- --height="0" \
- --quality="0"
+ --code aa \
+
+
+
diff --git a/docs/examples/avatars/get-credit-card.md b/docs/examples/avatars/get-credit-card.md
index a8e6cbd..365568b 100644
--- a/docs/examples/avatars/get-credit-card.md
+++ b/docs/examples/avatars/get-credit-card.md
@@ -1,5 +1,5 @@
appwrite avatars getCreditCard \
- --code="amex" \
- --width="0" \
- --height="0" \
- --quality="0"
+ --code amex \
+
+
+
diff --git a/docs/examples/avatars/get-favicon.md b/docs/examples/avatars/get-favicon.md
index 8cafa71..c658f1a 100644
--- a/docs/examples/avatars/get-favicon.md
+++ b/docs/examples/avatars/get-favicon.md
@@ -1,2 +1,2 @@
appwrite avatars getFavicon \
- --url="https://example.com"
+ --url https://example.com
diff --git a/docs/examples/avatars/get-flag.md b/docs/examples/avatars/get-flag.md
index 44c69ae..9f11fef 100644
--- a/docs/examples/avatars/get-flag.md
+++ b/docs/examples/avatars/get-flag.md
@@ -1,5 +1,5 @@
appwrite avatars getFlag \
- --code="af" \
- --width="0" \
- --height="0" \
- --quality="0"
+ --code af \
+
+
+
diff --git a/docs/examples/avatars/get-image.md b/docs/examples/avatars/get-image.md
index 2c7485e..7df1506 100644
--- a/docs/examples/avatars/get-image.md
+++ b/docs/examples/avatars/get-image.md
@@ -1,4 +1,4 @@
appwrite avatars getImage \
- --url="https://example.com" \
- --width="0" \
- --height="0"
+ --url https://example.com \
+
+
diff --git a/docs/examples/avatars/get-initials.md b/docs/examples/avatars/get-initials.md
index 8370da3..ff11a4f 100644
--- a/docs/examples/avatars/get-initials.md
+++ b/docs/examples/avatars/get-initials.md
@@ -1,6 +1,6 @@
appwrite avatars getInitials \
- --name="[NAME]" \
- --width="0" \
- --height="0" \
- --color="" \
- --background=""
+
+
+
+
+
diff --git a/docs/examples/avatars/get-q-r.md b/docs/examples/avatars/get-q-r.md
index b9215dc..855f339 100644
--- a/docs/examples/avatars/get-q-r.md
+++ b/docs/examples/avatars/get-q-r.md
@@ -1,5 +1,5 @@
appwrite avatars getQR \
- --text="[TEXT]" \
- --size="0" \
- --margin="0" \
- --download=""
+ --text [TEXT] \
+
+
+
diff --git a/docs/examples/database/create-boolean-attribute.md b/docs/examples/database/create-boolean-attribute.md
index d892a31..4fa1b8f 100644
--- a/docs/examples/database/create-boolean-attribute.md
+++ b/docs/examples/database/create-boolean-attribute.md
@@ -1,6 +1,6 @@
appwrite database createBooleanAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --required="" \
- --default="" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --required false \
+
+
diff --git a/docs/examples/database/create-collection.md b/docs/examples/database/create-collection.md
index 00cb3b5..c08c5da 100644
--- a/docs/examples/database/create-collection.md
+++ b/docs/examples/database/create-collection.md
@@ -1,6 +1,6 @@
appwrite database createCollection \
- --collectionId="[COLLECTION_ID]" \
- --name="[NAME]" \
- --permission="document" \
- --read="["role:all"]" \
- --write="["role:all"]"
+ --collectionId [COLLECTION_ID] \
+ --name [NAME] \
+ --permission document \
+ --read "role:all" \
+ --write "role:all"
diff --git a/docs/examples/database/create-document.md b/docs/examples/database/create-document.md
index d28577e..7fc2e7d 100644
--- a/docs/examples/database/create-document.md
+++ b/docs/examples/database/create-document.md
@@ -1,6 +1,6 @@
appwrite database createDocument \
- --collectionId="[COLLECTION_ID]" \
- --documentId="[DOCUMENT_ID]" \
- --data="{}" \
- --read="["role:all"]" \
- --write="["role:all"]"
+ --collectionId [COLLECTION_ID] \
+ --documentId [DOCUMENT_ID] \
+ --data '{ "key": "value" }' \
+
+
diff --git a/docs/examples/database/create-email-attribute.md b/docs/examples/database/create-email-attribute.md
index 1047774..649072b 100644
--- a/docs/examples/database/create-email-attribute.md
+++ b/docs/examples/database/create-email-attribute.md
@@ -1,6 +1,6 @@
appwrite database createEmailAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --required="" \
- --default="email@example.com" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --required false \
+
+
diff --git a/docs/examples/database/create-enum-attribute.md b/docs/examples/database/create-enum-attribute.md
index 72f1b9c..309a57b 100644
--- a/docs/examples/database/create-enum-attribute.md
+++ b/docs/examples/database/create-enum-attribute.md
@@ -1,7 +1,7 @@
appwrite database createEnumAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --elements="" \
- --required="" \
- --default="[DEFAULT]" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --elements one two three \
+ --required false \
+
+
diff --git a/docs/examples/database/create-float-attribute.md b/docs/examples/database/create-float-attribute.md
index abc4a55..5fff529 100644
--- a/docs/examples/database/create-float-attribute.md
+++ b/docs/examples/database/create-float-attribute.md
@@ -1,8 +1,8 @@
appwrite database createFloatAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --required="" \
- --min="" \
- --max="" \
- --default="" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --required false \
+
+
+
+
diff --git a/docs/examples/database/create-index.md b/docs/examples/database/create-index.md
index 8d66bb2..e2b3b5d 100644
--- a/docs/examples/database/create-index.md
+++ b/docs/examples/database/create-index.md
@@ -1,6 +1,6 @@
appwrite database createIndex \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --type="key" \
- --attributes="" \
- --orders=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --type key \
+ --attributes one two three \
+
diff --git a/docs/examples/database/create-integer-attribute.md b/docs/examples/database/create-integer-attribute.md
index 73abc3f..61546fe 100644
--- a/docs/examples/database/create-integer-attribute.md
+++ b/docs/examples/database/create-integer-attribute.md
@@ -1,8 +1,8 @@
appwrite database createIntegerAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --required="" \
- --min="" \
- --max="" \
- --default="" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --required false \
+
+
+
+
diff --git a/docs/examples/database/create-ip-attribute.md b/docs/examples/database/create-ip-attribute.md
index d3dd96e..19d40a7 100644
--- a/docs/examples/database/create-ip-attribute.md
+++ b/docs/examples/database/create-ip-attribute.md
@@ -1,6 +1,6 @@
appwrite database createIpAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --required="" \
- --default="" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --required false \
+
+
diff --git a/docs/examples/database/create-string-attribute.md b/docs/examples/database/create-string-attribute.md
index 6c0eaa3..542bc8e 100644
--- a/docs/examples/database/create-string-attribute.md
+++ b/docs/examples/database/create-string-attribute.md
@@ -1,7 +1,7 @@
appwrite database createStringAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --size="1" \
- --required="" \
- --default="[DEFAULT]" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --size 1 \
+ --required false \
+
+
diff --git a/docs/examples/database/create-url-attribute.md b/docs/examples/database/create-url-attribute.md
index bc965d4..1ff3380 100644
--- a/docs/examples/database/create-url-attribute.md
+++ b/docs/examples/database/create-url-attribute.md
@@ -1,6 +1,6 @@
appwrite database createUrlAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key="" \
- --required="" \
- --default="https://example.com" \
- --array=""
+ --collectionId [COLLECTION_ID] \
+ --key '' \
+ --required false \
+
+
diff --git a/docs/examples/database/delete-attribute.md b/docs/examples/database/delete-attribute.md
index 1a46094..435919b 100644
--- a/docs/examples/database/delete-attribute.md
+++ b/docs/examples/database/delete-attribute.md
@@ -1,3 +1,3 @@
appwrite database deleteAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key=""
+ --collectionId [COLLECTION_ID] \
+ --key ''
diff --git a/docs/examples/database/delete-collection.md b/docs/examples/database/delete-collection.md
index 3c36349..90cfde5 100644
--- a/docs/examples/database/delete-collection.md
+++ b/docs/examples/database/delete-collection.md
@@ -1,2 +1,2 @@
appwrite database deleteCollection \
- --collectionId="[COLLECTION_ID]"
+ --collectionId [COLLECTION_ID]
diff --git a/docs/examples/database/delete-document.md b/docs/examples/database/delete-document.md
index 24b8518..3987f90 100644
--- a/docs/examples/database/delete-document.md
+++ b/docs/examples/database/delete-document.md
@@ -1,3 +1,3 @@
appwrite database deleteDocument \
- --collectionId="[COLLECTION_ID]" \
- --documentId="[DOCUMENT_ID]"
+ --collectionId [COLLECTION_ID] \
+ --documentId [DOCUMENT_ID]
diff --git a/docs/examples/database/delete-index.md b/docs/examples/database/delete-index.md
index cd9db99..d3ac3c6 100644
--- a/docs/examples/database/delete-index.md
+++ b/docs/examples/database/delete-index.md
@@ -1,3 +1,3 @@
appwrite database deleteIndex \
- --collectionId="[COLLECTION_ID]" \
- --key=""
+ --collectionId [COLLECTION_ID] \
+ --key ''
diff --git a/docs/examples/database/get-attribute.md b/docs/examples/database/get-attribute.md
index d69f1e6..ef0a004 100644
--- a/docs/examples/database/get-attribute.md
+++ b/docs/examples/database/get-attribute.md
@@ -1,3 +1,3 @@
appwrite database getAttribute \
- --collectionId="[COLLECTION_ID]" \
- --key=""
+ --collectionId [COLLECTION_ID] \
+ --key ''
diff --git a/docs/examples/database/get-collection-usage.md b/docs/examples/database/get-collection-usage.md
new file mode 100644
index 0000000..e945936
--- /dev/null
+++ b/docs/examples/database/get-collection-usage.md
@@ -0,0 +1,3 @@
+appwrite database getCollectionUsage \
+ --collectionId [COLLECTION_ID] \
+
diff --git a/docs/examples/database/get-collection.md b/docs/examples/database/get-collection.md
index e7a1569..bfee02f 100644
--- a/docs/examples/database/get-collection.md
+++ b/docs/examples/database/get-collection.md
@@ -1,2 +1,2 @@
appwrite database getCollection \
- --collectionId="[COLLECTION_ID]"
+ --collectionId [COLLECTION_ID]
diff --git a/docs/examples/database/get-document.md b/docs/examples/database/get-document.md
index 32431ff..d1082b3 100644
--- a/docs/examples/database/get-document.md
+++ b/docs/examples/database/get-document.md
@@ -1,3 +1,3 @@
appwrite database getDocument \
- --collectionId="[COLLECTION_ID]" \
- --documentId="[DOCUMENT_ID]"
+ --collectionId [COLLECTION_ID] \
+ --documentId [DOCUMENT_ID]
diff --git a/docs/examples/database/get-index.md b/docs/examples/database/get-index.md
index e144097..d931f64 100644
--- a/docs/examples/database/get-index.md
+++ b/docs/examples/database/get-index.md
@@ -1,3 +1,3 @@
appwrite database getIndex \
- --collectionId="[COLLECTION_ID]" \
- --key=""
+ --collectionId [COLLECTION_ID] \
+ --key ''
diff --git a/docs/examples/database/get-usage.md b/docs/examples/database/get-usage.md
new file mode 100644
index 0000000..4c0611a
--- /dev/null
+++ b/docs/examples/database/get-usage.md
@@ -0,0 +1,2 @@
+appwrite database getUsage \
+
diff --git a/docs/examples/database/list-attributes.md b/docs/examples/database/list-attributes.md
index 24a89a0..164f110 100644
--- a/docs/examples/database/list-attributes.md
+++ b/docs/examples/database/list-attributes.md
@@ -1,2 +1,2 @@
appwrite database listAttributes \
- --collectionId="[COLLECTION_ID]"
+ --collectionId [COLLECTION_ID]
diff --git a/docs/examples/database/list-collection-logs.md b/docs/examples/database/list-collection-logs.md
new file mode 100644
index 0000000..d6dfcf5
--- /dev/null
+++ b/docs/examples/database/list-collection-logs.md
@@ -0,0 +1,4 @@
+appwrite database listCollectionLogs \
+ --collectionId [COLLECTION_ID] \
+
+
diff --git a/docs/examples/database/list-collections.md b/docs/examples/database/list-collections.md
index 9d655db..a81fd94 100644
--- a/docs/examples/database/list-collections.md
+++ b/docs/examples/database/list-collections.md
@@ -1,7 +1,7 @@
appwrite database listCollections \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
+
+
+
+
+
+
diff --git a/docs/examples/database/list-document-logs.md b/docs/examples/database/list-document-logs.md
new file mode 100644
index 0000000..dfe192e
--- /dev/null
+++ b/docs/examples/database/list-document-logs.md
@@ -0,0 +1,5 @@
+appwrite database listDocumentLogs \
+ --collectionId [COLLECTION_ID] \
+ --documentId [DOCUMENT_ID] \
+
+
diff --git a/docs/examples/database/list-documents.md b/docs/examples/database/list-documents.md
index 7c37175..cd295c6 100644
--- a/docs/examples/database/list-documents.md
+++ b/docs/examples/database/list-documents.md
@@ -1,9 +1,9 @@
appwrite database listDocuments \
- --collectionId="[COLLECTION_ID]" \
- --queries="" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderAttributes="" \
- --orderTypes=""
+ --collectionId [COLLECTION_ID] \
+
+
+
+
+
+
+
diff --git a/docs/examples/database/list-indexes.md b/docs/examples/database/list-indexes.md
index 3dd8916..ccfc13f 100644
--- a/docs/examples/database/list-indexes.md
+++ b/docs/examples/database/list-indexes.md
@@ -1,2 +1,2 @@
appwrite database listIndexes \
- --collectionId="[COLLECTION_ID]"
+ --collectionId [COLLECTION_ID]
diff --git a/docs/examples/database/update-collection.md b/docs/examples/database/update-collection.md
index 1c0670d..576fbe5 100644
--- a/docs/examples/database/update-collection.md
+++ b/docs/examples/database/update-collection.md
@@ -1,7 +1,7 @@
appwrite database updateCollection \
- --collectionId="[COLLECTION_ID]" \
- --name="[NAME]" \
- --permission="document" \
- --read="["role:all"]" \
- --write="["role:all"]" \
- --enabled=""
+ --collectionId [COLLECTION_ID] \
+ --name [NAME] \
+ --permission document \
+
+
+
diff --git a/docs/examples/database/update-document.md b/docs/examples/database/update-document.md
index 90a0c83..475ff0d 100644
--- a/docs/examples/database/update-document.md
+++ b/docs/examples/database/update-document.md
@@ -1,6 +1,6 @@
appwrite database updateDocument \
- --collectionId="[COLLECTION_ID]" \
- --documentId="[DOCUMENT_ID]" \
- --data="{}" \
- --read="["role:all"]" \
- --write="["role:all"]"
+ --collectionId [COLLECTION_ID] \
+ --documentId [DOCUMENT_ID] \
+ --data '{ "key": "value" }' \
+
+
diff --git a/docs/examples/functions/create-deployment.md b/docs/examples/functions/create-deployment.md
new file mode 100644
index 0000000..91e3173
--- /dev/null
+++ b/docs/examples/functions/create-deployment.md
@@ -0,0 +1,5 @@
+appwrite functions createDeployment \
+ --functionId [FUNCTION_ID] \
+ --entrypoint [ENTRYPOINT] \
+ --code 'path/to/file.png' \
+ --activate false
diff --git a/docs/examples/functions/create-execution.md b/docs/examples/functions/create-execution.md
index d13262d..adcb3cd 100644
--- a/docs/examples/functions/create-execution.md
+++ b/docs/examples/functions/create-execution.md
@@ -1,3 +1,4 @@
appwrite functions createExecution \
- --functionId="[FUNCTION_ID]" \
- --data="[DATA]"
+ --functionId [FUNCTION_ID] \
+
+
diff --git a/docs/examples/functions/create-tag.md b/docs/examples/functions/create-tag.md
deleted file mode 100644
index 4bd309c..0000000
--- a/docs/examples/functions/create-tag.md
+++ /dev/null
@@ -1,4 +0,0 @@
-appwrite functions createTag \
- --functionId="[FUNCTION_ID]" \
- --command="[COMMAND]" \
- --code=""
diff --git a/docs/examples/functions/create.md b/docs/examples/functions/create.md
index 30ae9a8..a9c7ec0 100644
--- a/docs/examples/functions/create.md
+++ b/docs/examples/functions/create.md
@@ -1,9 +1,9 @@
appwrite functions create \
- --functionId="[FUNCTION_ID]" \
- --name="[NAME]" \
- --execute="" \
- --runtime="node-14.5" \
- --vars="{}" \
- --events="" \
- --schedule="" \
- --timeout="1"
+ --functionId [FUNCTION_ID] \
+ --name [NAME] \
+ --execute one two three \
+ --runtime node-14.5 \
+
+
+
+
diff --git a/docs/examples/functions/delete-deployment.md b/docs/examples/functions/delete-deployment.md
new file mode 100644
index 0000000..2033b84
--- /dev/null
+++ b/docs/examples/functions/delete-deployment.md
@@ -0,0 +1,3 @@
+appwrite functions deleteDeployment \
+ --functionId [FUNCTION_ID] \
+ --deploymentId [DEPLOYMENT_ID]
diff --git a/docs/examples/functions/delete-tag.md b/docs/examples/functions/delete-tag.md
deleted file mode 100644
index c4bca03..0000000
--- a/docs/examples/functions/delete-tag.md
+++ /dev/null
@@ -1,3 +0,0 @@
-appwrite functions deleteTag \
- --functionId="[FUNCTION_ID]" \
- --tagId="[TAG_ID]"
diff --git a/docs/examples/functions/delete.md b/docs/examples/functions/delete.md
index f05bb7d..b3ce304 100644
--- a/docs/examples/functions/delete.md
+++ b/docs/examples/functions/delete.md
@@ -1,2 +1,2 @@
appwrite functions delete \
- --functionId="[FUNCTION_ID]"
+ --functionId [FUNCTION_ID]
diff --git a/docs/examples/functions/get-deployment.md b/docs/examples/functions/get-deployment.md
new file mode 100644
index 0000000..668bcde
--- /dev/null
+++ b/docs/examples/functions/get-deployment.md
@@ -0,0 +1,3 @@
+appwrite functions getDeployment \
+ --functionId [FUNCTION_ID] \
+ --deploymentId [DEPLOYMENT_ID]
diff --git a/docs/examples/functions/get-execution.md b/docs/examples/functions/get-execution.md
index 33b149b..b6a9747 100644
--- a/docs/examples/functions/get-execution.md
+++ b/docs/examples/functions/get-execution.md
@@ -1,3 +1,3 @@
appwrite functions getExecution \
- --functionId="[FUNCTION_ID]" \
- --executionId="[EXECUTION_ID]"
+ --functionId [FUNCTION_ID] \
+ --executionId [EXECUTION_ID]
diff --git a/docs/examples/functions/get-tag.md b/docs/examples/functions/get-tag.md
deleted file mode 100644
index 769d709..0000000
--- a/docs/examples/functions/get-tag.md
+++ /dev/null
@@ -1,3 +0,0 @@
-appwrite functions getTag \
- --functionId="[FUNCTION_ID]" \
- --tagId="[TAG_ID]"
diff --git a/docs/examples/functions/get-usage.md b/docs/examples/functions/get-usage.md
new file mode 100644
index 0000000..1c2cf27
--- /dev/null
+++ b/docs/examples/functions/get-usage.md
@@ -0,0 +1,3 @@
+appwrite functions getUsage \
+ --functionId [FUNCTION_ID] \
+
diff --git a/docs/examples/functions/get.md b/docs/examples/functions/get.md
index 44bb0f0..0332c4a 100644
--- a/docs/examples/functions/get.md
+++ b/docs/examples/functions/get.md
@@ -1,2 +1,2 @@
appwrite functions get \
- --functionId="[FUNCTION_ID]"
+ --functionId [FUNCTION_ID]
diff --git a/docs/examples/functions/list-deployments.md b/docs/examples/functions/list-deployments.md
new file mode 100644
index 0000000..1dc4325
--- /dev/null
+++ b/docs/examples/functions/list-deployments.md
@@ -0,0 +1,8 @@
+appwrite functions listDeployments \
+ --functionId [FUNCTION_ID] \
+
+
+
+
+
+
diff --git a/docs/examples/functions/list-executions.md b/docs/examples/functions/list-executions.md
index 088ce67..9eec5b9 100644
--- a/docs/examples/functions/list-executions.md
+++ b/docs/examples/functions/list-executions.md
@@ -1,7 +1,7 @@
appwrite functions listExecutions \
- --functionId="[FUNCTION_ID]" \
- --limit="0" \
- --offset="0" \
- --search="[SEARCH]" \
- --cursor="[CURSOR]" \
- --cursorDirection="after"
+ --functionId [FUNCTION_ID] \
+
+
+
+
+
diff --git a/docs/examples/functions/list-tags.md b/docs/examples/functions/list-tags.md
deleted file mode 100644
index d675cf4..0000000
--- a/docs/examples/functions/list-tags.md
+++ /dev/null
@@ -1,8 +0,0 @@
-appwrite functions listTags \
- --functionId="[FUNCTION_ID]" \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
diff --git a/docs/examples/functions/list.md b/docs/examples/functions/list.md
index 9bcae19..40ace98 100644
--- a/docs/examples/functions/list.md
+++ b/docs/examples/functions/list.md
@@ -1,7 +1,7 @@
appwrite functions list \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
+
+
+
+
+
+
diff --git a/docs/examples/functions/retry-build.md b/docs/examples/functions/retry-build.md
new file mode 100644
index 0000000..bd226b7
--- /dev/null
+++ b/docs/examples/functions/retry-build.md
@@ -0,0 +1,4 @@
+appwrite functions retryBuild \
+ --functionId [FUNCTION_ID] \
+ --deploymentId [DEPLOYMENT_ID] \
+ --buildId [BUILD_ID]
diff --git a/docs/examples/functions/update-deployment.md b/docs/examples/functions/update-deployment.md
new file mode 100644
index 0000000..7276b3e
--- /dev/null
+++ b/docs/examples/functions/update-deployment.md
@@ -0,0 +1,3 @@
+appwrite functions updateDeployment \
+ --functionId [FUNCTION_ID] \
+ --deploymentId [DEPLOYMENT_ID]
diff --git a/docs/examples/functions/update-tag.md b/docs/examples/functions/update-tag.md
deleted file mode 100644
index 246b6f3..0000000
--- a/docs/examples/functions/update-tag.md
+++ /dev/null
@@ -1,3 +0,0 @@
-appwrite functions updateTag \
- --functionId="[FUNCTION_ID]" \
- --tag="[TAG]"
diff --git a/docs/examples/functions/update.md b/docs/examples/functions/update.md
index b59d2de..d0557d9 100644
--- a/docs/examples/functions/update.md
+++ b/docs/examples/functions/update.md
@@ -1,8 +1,8 @@
appwrite functions update \
- --functionId="[FUNCTION_ID]" \
- --name="[NAME]" \
- --execute="" \
- --vars="{}" \
- --events="" \
- --schedule="" \
- --timeout="1"
+ --functionId [FUNCTION_ID] \
+ --name [NAME] \
+ --execute one two three \
+
+
+
+
diff --git a/docs/examples/projects/create-domain.md b/docs/examples/projects/create-domain.md
new file mode 100644
index 0000000..6ae89cc
--- /dev/null
+++ b/docs/examples/projects/create-domain.md
@@ -0,0 +1,3 @@
+appwrite projects createDomain \
+ --projectId [PROJECT_ID] \
+ --domain ''
diff --git a/docs/examples/projects/create-key.md b/docs/examples/projects/create-key.md
new file mode 100644
index 0000000..c0a7983
--- /dev/null
+++ b/docs/examples/projects/create-key.md
@@ -0,0 +1,4 @@
+appwrite projects createKey \
+ --projectId [PROJECT_ID] \
+ --name [NAME] \
+ --scopes one two three
diff --git a/docs/examples/projects/create-platform.md b/docs/examples/projects/create-platform.md
new file mode 100644
index 0000000..1374f51
--- /dev/null
+++ b/docs/examples/projects/create-platform.md
@@ -0,0 +1,7 @@
+appwrite projects createPlatform \
+ --projectId [PROJECT_ID] \
+ --type web \
+ --name [NAME] \
+
+
+
diff --git a/docs/examples/projects/create-webhook.md b/docs/examples/projects/create-webhook.md
new file mode 100644
index 0000000..2eaacd1
--- /dev/null
+++ b/docs/examples/projects/create-webhook.md
@@ -0,0 +1,8 @@
+appwrite projects createWebhook \
+ --projectId [PROJECT_ID] \
+ --name [NAME] \
+ --events one two three \
+ --url https://example.com \
+ --security false \
+
+
diff --git a/docs/examples/projects/create.md b/docs/examples/projects/create.md
new file mode 100644
index 0000000..3638e11
--- /dev/null
+++ b/docs/examples/projects/create.md
@@ -0,0 +1,13 @@
+appwrite projects create \
+ --projectId [PROJECT_ID] \
+ --name [NAME] \
+ --teamId [TEAM_ID] \
+
+
+
+
+
+
+
+
+
diff --git a/docs/examples/projects/delete-domain.md b/docs/examples/projects/delete-domain.md
new file mode 100644
index 0000000..c469008
--- /dev/null
+++ b/docs/examples/projects/delete-domain.md
@@ -0,0 +1,3 @@
+appwrite projects deleteDomain \
+ --projectId [PROJECT_ID] \
+ --domainId [DOMAIN_ID]
diff --git a/docs/examples/projects/delete-key.md b/docs/examples/projects/delete-key.md
new file mode 100644
index 0000000..48f97cf
--- /dev/null
+++ b/docs/examples/projects/delete-key.md
@@ -0,0 +1,3 @@
+appwrite projects deleteKey \
+ --projectId [PROJECT_ID] \
+ --keyId [KEY_ID]
diff --git a/docs/examples/projects/delete-platform.md b/docs/examples/projects/delete-platform.md
new file mode 100644
index 0000000..9e14cb5
--- /dev/null
+++ b/docs/examples/projects/delete-platform.md
@@ -0,0 +1,3 @@
+appwrite projects deletePlatform \
+ --projectId [PROJECT_ID] \
+ --platformId [PLATFORM_ID]
diff --git a/docs/examples/projects/delete-webhook.md b/docs/examples/projects/delete-webhook.md
new file mode 100644
index 0000000..1235e73
--- /dev/null
+++ b/docs/examples/projects/delete-webhook.md
@@ -0,0 +1,3 @@
+appwrite projects deleteWebhook \
+ --projectId [PROJECT_ID] \
+ --webhookId [WEBHOOK_ID]
diff --git a/docs/examples/projects/delete.md b/docs/examples/projects/delete.md
new file mode 100644
index 0000000..99a21b1
--- /dev/null
+++ b/docs/examples/projects/delete.md
@@ -0,0 +1,3 @@
+appwrite projects delete \
+ --projectId [PROJECT_ID] \
+ --password password
diff --git a/docs/examples/projects/get-domain.md b/docs/examples/projects/get-domain.md
new file mode 100644
index 0000000..367679a
--- /dev/null
+++ b/docs/examples/projects/get-domain.md
@@ -0,0 +1,3 @@
+appwrite projects getDomain \
+ --projectId [PROJECT_ID] \
+ --domainId [DOMAIN_ID]
diff --git a/docs/examples/projects/get-key.md b/docs/examples/projects/get-key.md
new file mode 100644
index 0000000..75548d2
--- /dev/null
+++ b/docs/examples/projects/get-key.md
@@ -0,0 +1,3 @@
+appwrite projects getKey \
+ --projectId [PROJECT_ID] \
+ --keyId [KEY_ID]
diff --git a/docs/examples/projects/get-platform.md b/docs/examples/projects/get-platform.md
new file mode 100644
index 0000000..97432f0
--- /dev/null
+++ b/docs/examples/projects/get-platform.md
@@ -0,0 +1,3 @@
+appwrite projects getPlatform \
+ --projectId [PROJECT_ID] \
+ --platformId [PLATFORM_ID]
diff --git a/docs/examples/projects/get-usage.md b/docs/examples/projects/get-usage.md
new file mode 100644
index 0000000..a10e474
--- /dev/null
+++ b/docs/examples/projects/get-usage.md
@@ -0,0 +1,3 @@
+appwrite projects getUsage \
+ --projectId [PROJECT_ID] \
+
diff --git a/docs/examples/projects/get-webhook.md b/docs/examples/projects/get-webhook.md
new file mode 100644
index 0000000..b51a78c
--- /dev/null
+++ b/docs/examples/projects/get-webhook.md
@@ -0,0 +1,3 @@
+appwrite projects getWebhook \
+ --projectId [PROJECT_ID] \
+ --webhookId [WEBHOOK_ID]
diff --git a/docs/examples/projects/get.md b/docs/examples/projects/get.md
new file mode 100644
index 0000000..b0589ea
--- /dev/null
+++ b/docs/examples/projects/get.md
@@ -0,0 +1,2 @@
+appwrite projects get \
+ --projectId [PROJECT_ID]
diff --git a/docs/examples/projects/list-domains.md b/docs/examples/projects/list-domains.md
new file mode 100644
index 0000000..2967713
--- /dev/null
+++ b/docs/examples/projects/list-domains.md
@@ -0,0 +1,2 @@
+appwrite projects listDomains \
+ --projectId [PROJECT_ID]
diff --git a/docs/examples/projects/list-keys.md b/docs/examples/projects/list-keys.md
new file mode 100644
index 0000000..aba2fab
--- /dev/null
+++ b/docs/examples/projects/list-keys.md
@@ -0,0 +1,2 @@
+appwrite projects listKeys \
+ --projectId [PROJECT_ID]
diff --git a/docs/examples/projects/list-platforms.md b/docs/examples/projects/list-platforms.md
new file mode 100644
index 0000000..cd7ae37
--- /dev/null
+++ b/docs/examples/projects/list-platforms.md
@@ -0,0 +1,2 @@
+appwrite projects listPlatforms \
+ --projectId [PROJECT_ID]
diff --git a/docs/examples/projects/list-webhooks.md b/docs/examples/projects/list-webhooks.md
new file mode 100644
index 0000000..cda3f1e
--- /dev/null
+++ b/docs/examples/projects/list-webhooks.md
@@ -0,0 +1,2 @@
+appwrite projects listWebhooks \
+ --projectId [PROJECT_ID]
diff --git a/docs/examples/projects/list.md b/docs/examples/projects/list.md
new file mode 100644
index 0000000..ca4d5e7
--- /dev/null
+++ b/docs/examples/projects/list.md
@@ -0,0 +1,7 @@
+appwrite projects list \
+
+
+
+
+
+
diff --git a/docs/examples/projects/update-auth-limit.md b/docs/examples/projects/update-auth-limit.md
new file mode 100644
index 0000000..0f59c96
--- /dev/null
+++ b/docs/examples/projects/update-auth-limit.md
@@ -0,0 +1,3 @@
+appwrite projects updateAuthLimit \
+ --projectId [PROJECT_ID] \
+ --limit 0
diff --git a/docs/examples/projects/update-auth-status.md b/docs/examples/projects/update-auth-status.md
new file mode 100644
index 0000000..c4348c1
--- /dev/null
+++ b/docs/examples/projects/update-auth-status.md
@@ -0,0 +1,4 @@
+appwrite projects updateAuthStatus \
+ --projectId [PROJECT_ID] \
+ --method email-password \
+ --status false
diff --git a/docs/examples/projects/update-domain-verification.md b/docs/examples/projects/update-domain-verification.md
new file mode 100644
index 0000000..bb07cdb
--- /dev/null
+++ b/docs/examples/projects/update-domain-verification.md
@@ -0,0 +1,3 @@
+appwrite projects updateDomainVerification \
+ --projectId [PROJECT_ID] \
+ --domainId [DOMAIN_ID]
diff --git a/docs/examples/projects/update-key.md b/docs/examples/projects/update-key.md
new file mode 100644
index 0000000..0e49afa
--- /dev/null
+++ b/docs/examples/projects/update-key.md
@@ -0,0 +1,5 @@
+appwrite projects updateKey \
+ --projectId [PROJECT_ID] \
+ --keyId [KEY_ID] \
+ --name [NAME] \
+ --scopes one two three
diff --git a/docs/examples/projects/update-o-auth2.md b/docs/examples/projects/update-o-auth2.md
new file mode 100644
index 0000000..bf9dea6
--- /dev/null
+++ b/docs/examples/projects/update-o-auth2.md
@@ -0,0 +1,5 @@
+appwrite projects updateOAuth2 \
+ --projectId [PROJECT_ID] \
+ --provider amazon \
+
+
diff --git a/docs/examples/projects/update-platform.md b/docs/examples/projects/update-platform.md
new file mode 100644
index 0000000..77268a4
--- /dev/null
+++ b/docs/examples/projects/update-platform.md
@@ -0,0 +1,7 @@
+appwrite projects updatePlatform \
+ --projectId [PROJECT_ID] \
+ --platformId [PLATFORM_ID] \
+ --name [NAME] \
+
+
+
diff --git a/docs/examples/projects/update-service-status.md b/docs/examples/projects/update-service-status.md
new file mode 100644
index 0000000..4cfd9f9
--- /dev/null
+++ b/docs/examples/projects/update-service-status.md
@@ -0,0 +1,4 @@
+appwrite projects updateServiceStatus \
+ --projectId [PROJECT_ID] \
+ --service account \
+ --status false
diff --git a/docs/examples/projects/update-webhook.md b/docs/examples/projects/update-webhook.md
new file mode 100644
index 0000000..98517cb
--- /dev/null
+++ b/docs/examples/projects/update-webhook.md
@@ -0,0 +1,9 @@
+appwrite projects updateWebhook \
+ --projectId [PROJECT_ID] \
+ --webhookId [WEBHOOK_ID] \
+ --name [NAME] \
+ --events one two three \
+ --url https://example.com \
+ --security false \
+
+
diff --git a/docs/examples/projects/update.md b/docs/examples/projects/update.md
new file mode 100644
index 0000000..83e99a1
--- /dev/null
+++ b/docs/examples/projects/update.md
@@ -0,0 +1,12 @@
+appwrite projects update \
+ --projectId [PROJECT_ID] \
+ --name [NAME] \
+
+
+
+
+
+
+
+
+
diff --git a/docs/examples/storage/create-bucket.md b/docs/examples/storage/create-bucket.md
new file mode 100644
index 0000000..0ccfdb0
--- /dev/null
+++ b/docs/examples/storage/create-bucket.md
@@ -0,0 +1,11 @@
+appwrite storage createBucket \
+ --bucketId [BUCKET_ID] \
+ --name [NAME] \
+ --permission file \
+
+
+
+
+
+
+
diff --git a/docs/examples/storage/create-file.md b/docs/examples/storage/create-file.md
index da19fc9..eaa8f9b 100644
--- a/docs/examples/storage/create-file.md
+++ b/docs/examples/storage/create-file.md
@@ -1,5 +1,6 @@
appwrite storage createFile \
- --fileId="[FILE_ID]" \
- --file="" \
- --read="" \
- --write=""
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID] \
+ --file 'path/to/file.png' \
+
+
diff --git a/docs/examples/storage/delete-bucket.md b/docs/examples/storage/delete-bucket.md
new file mode 100644
index 0000000..178a6a4
--- /dev/null
+++ b/docs/examples/storage/delete-bucket.md
@@ -0,0 +1,2 @@
+appwrite storage deleteBucket \
+ --bucketId [BUCKET_ID]
diff --git a/docs/examples/storage/delete-file.md b/docs/examples/storage/delete-file.md
index ecc8eba..0275f87 100644
--- a/docs/examples/storage/delete-file.md
+++ b/docs/examples/storage/delete-file.md
@@ -1,2 +1,3 @@
appwrite storage deleteFile \
- --fileId="[FILE_ID]"
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID]
diff --git a/docs/examples/storage/get-bucket-usage.md b/docs/examples/storage/get-bucket-usage.md
new file mode 100644
index 0000000..930575e
--- /dev/null
+++ b/docs/examples/storage/get-bucket-usage.md
@@ -0,0 +1,3 @@
+appwrite storage getBucketUsage \
+ --bucketId [BUCKET_ID] \
+
diff --git a/docs/examples/storage/get-bucket.md b/docs/examples/storage/get-bucket.md
new file mode 100644
index 0000000..76479be
--- /dev/null
+++ b/docs/examples/storage/get-bucket.md
@@ -0,0 +1,2 @@
+appwrite storage getBucket \
+ --bucketId [BUCKET_ID]
diff --git a/docs/examples/storage/get-file-download.md b/docs/examples/storage/get-file-download.md
index 230eb55..637c7db 100644
--- a/docs/examples/storage/get-file-download.md
+++ b/docs/examples/storage/get-file-download.md
@@ -1,2 +1,3 @@
appwrite storage getFileDownload \
- --fileId="[FILE_ID]"
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID]
diff --git a/docs/examples/storage/get-file-preview.md b/docs/examples/storage/get-file-preview.md
index ed25491..3090885 100644
--- a/docs/examples/storage/get-file-preview.md
+++ b/docs/examples/storage/get-file-preview.md
@@ -1,13 +1,14 @@
appwrite storage getFilePreview \
- --fileId="[FILE_ID]" \
- --width="0" \
- --height="0" \
- --gravity="center" \
- --quality="0" \
- --borderWidth="0" \
- --borderColor="" \
- --borderRadius="0" \
- --opacity="0" \
- --rotation="-360" \
- --background="" \
- --output="jpg"
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID] \
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/examples/storage/get-file-view.md b/docs/examples/storage/get-file-view.md
index f12850a..a8500f3 100644
--- a/docs/examples/storage/get-file-view.md
+++ b/docs/examples/storage/get-file-view.md
@@ -1,2 +1,3 @@
appwrite storage getFileView \
- --fileId="[FILE_ID]"
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID]
diff --git a/docs/examples/storage/get-file.md b/docs/examples/storage/get-file.md
index 6861d99..f556ef1 100644
--- a/docs/examples/storage/get-file.md
+++ b/docs/examples/storage/get-file.md
@@ -1,2 +1,3 @@
appwrite storage getFile \
- --fileId="[FILE_ID]"
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID]
diff --git a/docs/examples/storage/get-usage.md b/docs/examples/storage/get-usage.md
new file mode 100644
index 0000000..29466e0
--- /dev/null
+++ b/docs/examples/storage/get-usage.md
@@ -0,0 +1,2 @@
+appwrite storage getUsage \
+
diff --git a/docs/examples/storage/list-buckets.md b/docs/examples/storage/list-buckets.md
new file mode 100644
index 0000000..2245c6c
--- /dev/null
+++ b/docs/examples/storage/list-buckets.md
@@ -0,0 +1,7 @@
+appwrite storage listBuckets \
+
+
+
+
+
+
diff --git a/docs/examples/storage/list-files.md b/docs/examples/storage/list-files.md
index a233551..c0a7b1b 100644
--- a/docs/examples/storage/list-files.md
+++ b/docs/examples/storage/list-files.md
@@ -1,7 +1,8 @@
appwrite storage listFiles \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
+ --bucketId [BUCKET_ID] \
+
+
+
+
+
+
diff --git a/docs/examples/storage/update-bucket.md b/docs/examples/storage/update-bucket.md
new file mode 100644
index 0000000..9fc6b80
--- /dev/null
+++ b/docs/examples/storage/update-bucket.md
@@ -0,0 +1,11 @@
+appwrite storage updateBucket \
+ --bucketId [BUCKET_ID] \
+ --name [NAME] \
+ --permission file \
+
+
+
+
+
+
+
diff --git a/docs/examples/storage/update-file.md b/docs/examples/storage/update-file.md
index 185df74..6f6a9ca 100644
--- a/docs/examples/storage/update-file.md
+++ b/docs/examples/storage/update-file.md
@@ -1,4 +1,5 @@
appwrite storage updateFile \
- --fileId="[FILE_ID]" \
- --read="" \
- --write=""
+ --bucketId [BUCKET_ID] \
+ --fileId [FILE_ID] \
+
+
diff --git a/docs/examples/teams/create-membership.md b/docs/examples/teams/create-membership.md
index 1e05cf8..351213c 100644
--- a/docs/examples/teams/create-membership.md
+++ b/docs/examples/teams/create-membership.md
@@ -1,6 +1,6 @@
appwrite teams createMembership \
- --teamId="[TEAM_ID]" \
- --email="email@example.com" \
- --roles="" \
- --url="https://example.com" \
- --name="[NAME]"
+ --teamId [TEAM_ID] \
+ --email email@example.com \
+ --roles one two three \
+ --url https://example.com \
+
diff --git a/docs/examples/teams/create.md b/docs/examples/teams/create.md
index c494cb9..3704d02 100644
--- a/docs/examples/teams/create.md
+++ b/docs/examples/teams/create.md
@@ -1,4 +1,4 @@
appwrite teams create \
- --teamId="[TEAM_ID]" \
- --name="[NAME]" \
- --roles=""
+ --teamId [TEAM_ID] \
+ --name [NAME] \
+
diff --git a/docs/examples/teams/delete-membership.md b/docs/examples/teams/delete-membership.md
index f3b36a6..6aaaf89 100644
--- a/docs/examples/teams/delete-membership.md
+++ b/docs/examples/teams/delete-membership.md
@@ -1,3 +1,3 @@
appwrite teams deleteMembership \
- --teamId="[TEAM_ID]" \
- --membershipId="[MEMBERSHIP_ID]"
+ --teamId [TEAM_ID] \
+ --membershipId [MEMBERSHIP_ID]
diff --git a/docs/examples/teams/delete.md b/docs/examples/teams/delete.md
index 14a5388..0a4d554 100644
--- a/docs/examples/teams/delete.md
+++ b/docs/examples/teams/delete.md
@@ -1,2 +1,2 @@
appwrite teams delete \
- --teamId="[TEAM_ID]"
+ --teamId [TEAM_ID]
diff --git a/docs/examples/teams/get-membership.md b/docs/examples/teams/get-membership.md
index 47ece4e..25d1186 100644
--- a/docs/examples/teams/get-membership.md
+++ b/docs/examples/teams/get-membership.md
@@ -1,3 +1,3 @@
appwrite teams getMembership \
- --teamId="[TEAM_ID]" \
- --membershipId="[MEMBERSHIP_ID]"
+ --teamId [TEAM_ID] \
+ --membershipId [MEMBERSHIP_ID]
diff --git a/docs/examples/teams/get-memberships.md b/docs/examples/teams/get-memberships.md
index a4b0e54..2ce366b 100644
--- a/docs/examples/teams/get-memberships.md
+++ b/docs/examples/teams/get-memberships.md
@@ -1,8 +1,8 @@
appwrite teams getMemberships \
- --teamId="[TEAM_ID]" \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
+ --teamId [TEAM_ID] \
+
+
+
+
+
+
diff --git a/docs/examples/teams/get.md b/docs/examples/teams/get.md
index 6de2aa8..111aff6 100644
--- a/docs/examples/teams/get.md
+++ b/docs/examples/teams/get.md
@@ -1,2 +1,2 @@
appwrite teams get \
- --teamId="[TEAM_ID]"
+ --teamId [TEAM_ID]
diff --git a/docs/examples/teams/list.md b/docs/examples/teams/list.md
index 1cc806c..f2cf1be 100644
--- a/docs/examples/teams/list.md
+++ b/docs/examples/teams/list.md
@@ -1,7 +1,7 @@
appwrite teams list \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
+
+
+
+
+
+
diff --git a/docs/examples/teams/update-membership-roles.md b/docs/examples/teams/update-membership-roles.md
index 2b19a15..c6684d2 100644
--- a/docs/examples/teams/update-membership-roles.md
+++ b/docs/examples/teams/update-membership-roles.md
@@ -1,4 +1,4 @@
appwrite teams updateMembershipRoles \
- --teamId="[TEAM_ID]" \
- --membershipId="[MEMBERSHIP_ID]" \
- --roles=""
+ --teamId [TEAM_ID] \
+ --membershipId [MEMBERSHIP_ID] \
+ --roles one two three
diff --git a/docs/examples/teams/update-membership-status.md b/docs/examples/teams/update-membership-status.md
index 1da1a74..0f3efc4 100644
--- a/docs/examples/teams/update-membership-status.md
+++ b/docs/examples/teams/update-membership-status.md
@@ -1,5 +1,5 @@
appwrite teams updateMembershipStatus \
- --teamId="[TEAM_ID]" \
- --membershipId="[MEMBERSHIP_ID]" \
- --userId="[USER_ID]" \
- --secret="[SECRET]"
+ --teamId [TEAM_ID] \
+ --membershipId [MEMBERSHIP_ID] \
+ --userId [USER_ID] \
+ --secret [SECRET]
diff --git a/docs/examples/teams/update.md b/docs/examples/teams/update.md
index 3e37907..4298ea5 100644
--- a/docs/examples/teams/update.md
+++ b/docs/examples/teams/update.md
@@ -1,3 +1,3 @@
appwrite teams update \
- --teamId="[TEAM_ID]" \
- --name="[NAME]"
+ --teamId [TEAM_ID] \
+ --name [NAME]
diff --git a/docs/examples/users/create.md b/docs/examples/users/create.md
index 0d2425f..ccf46cc 100644
--- a/docs/examples/users/create.md
+++ b/docs/examples/users/create.md
@@ -1,5 +1,5 @@
appwrite users create \
- --userId="[USER_ID]" \
- --email="email@example.com" \
- --password="password" \
- --name="[NAME]"
+ --userId [USER_ID] \
+ --email email@example.com \
+ --password password \
+
diff --git a/docs/examples/users/delete-session.md b/docs/examples/users/delete-session.md
index e46fb20..e4b7632 100644
--- a/docs/examples/users/delete-session.md
+++ b/docs/examples/users/delete-session.md
@@ -1,3 +1,3 @@
appwrite users deleteSession \
- --userId="[USER_ID]" \
- --sessionId="[SESSION_ID]"
+ --userId [USER_ID] \
+ --sessionId [SESSION_ID]
diff --git a/docs/examples/users/delete-sessions.md b/docs/examples/users/delete-sessions.md
index c9db0c5..16c2c3a 100644
--- a/docs/examples/users/delete-sessions.md
+++ b/docs/examples/users/delete-sessions.md
@@ -1,2 +1,2 @@
appwrite users deleteSessions \
- --userId="[USER_ID]"
+ --userId [USER_ID]
diff --git a/docs/examples/users/delete.md b/docs/examples/users/delete.md
index 22b5b16..9c24060 100644
--- a/docs/examples/users/delete.md
+++ b/docs/examples/users/delete.md
@@ -1,2 +1,2 @@
appwrite users delete \
- --userId="[USER_ID]"
+ --userId [USER_ID]
diff --git a/docs/examples/users/get-logs.md b/docs/examples/users/get-logs.md
index f013d5b..dfc1744 100644
--- a/docs/examples/users/get-logs.md
+++ b/docs/examples/users/get-logs.md
@@ -1,4 +1,4 @@
appwrite users getLogs \
- --userId="[USER_ID]" \
- --limit="0" \
- --offset="0"
+ --userId [USER_ID] \
+
+
diff --git a/docs/examples/users/get-prefs.md b/docs/examples/users/get-prefs.md
index 7dbfc03..1aa1b1e 100644
--- a/docs/examples/users/get-prefs.md
+++ b/docs/examples/users/get-prefs.md
@@ -1,2 +1,2 @@
appwrite users getPrefs \
- --userId="[USER_ID]"
+ --userId [USER_ID]
diff --git a/docs/examples/users/get-sessions.md b/docs/examples/users/get-sessions.md
index 0172a17..432b35c 100644
--- a/docs/examples/users/get-sessions.md
+++ b/docs/examples/users/get-sessions.md
@@ -1,2 +1,2 @@
appwrite users getSessions \
- --userId="[USER_ID]"
+ --userId [USER_ID]
diff --git a/docs/examples/users/get-usage.md b/docs/examples/users/get-usage.md
new file mode 100644
index 0000000..860cdc0
--- /dev/null
+++ b/docs/examples/users/get-usage.md
@@ -0,0 +1,3 @@
+appwrite users getUsage \
+
+
diff --git a/docs/examples/users/get.md b/docs/examples/users/get.md
index 895fd37..95f44af 100644
--- a/docs/examples/users/get.md
+++ b/docs/examples/users/get.md
@@ -1,2 +1,2 @@
appwrite users get \
- --userId="[USER_ID]"
+ --userId [USER_ID]
diff --git a/docs/examples/users/list.md b/docs/examples/users/list.md
index 1f92a51..79bd22c 100644
--- a/docs/examples/users/list.md
+++ b/docs/examples/users/list.md
@@ -1,7 +1,7 @@
appwrite users list \
- --search="[SEARCH]" \
- --limit="0" \
- --offset="0" \
- --cursor="[CURSOR]" \
- --cursorDirection="after" \
- --orderType="ASC"
+
+
+
+
+
+
diff --git a/docs/examples/users/update-email.md b/docs/examples/users/update-email.md
index ab0b778..be8bb11 100644
--- a/docs/examples/users/update-email.md
+++ b/docs/examples/users/update-email.md
@@ -1,3 +1,3 @@
appwrite users updateEmail \
- --userId="[USER_ID]" \
- --email="email@example.com"
+ --userId [USER_ID] \
+ --email email@example.com
diff --git a/docs/examples/users/update-name.md b/docs/examples/users/update-name.md
index 69da4d5..ce9cad5 100644
--- a/docs/examples/users/update-name.md
+++ b/docs/examples/users/update-name.md
@@ -1,3 +1,3 @@
appwrite users updateName \
- --userId="[USER_ID]" \
- --name="[NAME]"
+ --userId [USER_ID] \
+ --name [NAME]
diff --git a/docs/examples/users/update-password.md b/docs/examples/users/update-password.md
index 05dc02d..1678467 100644
--- a/docs/examples/users/update-password.md
+++ b/docs/examples/users/update-password.md
@@ -1,3 +1,3 @@
appwrite users updatePassword \
- --userId="[USER_ID]" \
- --password="password"
+ --userId [USER_ID] \
+ --password password
diff --git a/docs/examples/users/update-prefs.md b/docs/examples/users/update-prefs.md
index b80ae2c..cc4a742 100644
--- a/docs/examples/users/update-prefs.md
+++ b/docs/examples/users/update-prefs.md
@@ -1,3 +1,3 @@
appwrite users updatePrefs \
- --userId="[USER_ID]" \
- --prefs="{}"
+ --userId [USER_ID] \
+ --prefs '{ "key": "value" }'
diff --git a/docs/examples/users/update-status.md b/docs/examples/users/update-status.md
index 00fbb4b..6bc10ee 100644
--- a/docs/examples/users/update-status.md
+++ b/docs/examples/users/update-status.md
@@ -1,3 +1,3 @@
appwrite users updateStatus \
- --userId="[USER_ID]" \
- --status=""
+ --userId [USER_ID] \
+ --status false
diff --git a/docs/examples/users/update-verification.md b/docs/examples/users/update-verification.md
index 569f440..edc5934 100644
--- a/docs/examples/users/update-verification.md
+++ b/docs/examples/users/update-verification.md
@@ -1,3 +1,3 @@
appwrite users updateVerification \
- --userId="[USER_ID]" \
- --emailVerification=""
+ --userId [USER_ID] \
+ --emailVerification false
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..43c8613
--- /dev/null
+++ b/index.js
@@ -0,0 +1,49 @@
+#! /usr/bin/env node
+const program = require("commander");
+const chalk = require("chalk");
+const { version } = require("./package.json");
+const { commandDescriptions, cliConfig } = require("./lib/parser");
+const { client } = require("./lib/commands/generic");
+const { login, logout } = require("./lib/commands/generic");
+const { init } = require("./lib/commands/init");
+const { deploy } = require("./lib/commands/deploy");
+const { account } = require("./lib/commands/account");
+const { avatars } = require("./lib/commands/avatars");
+const { database } = require("./lib/commands/database");
+const { functions } = require("./lib/commands/functions");
+const { health } = require("./lib/commands/health");
+const { locale } = require("./lib/commands/locale");
+const { projects } = require("./lib/commands/projects");
+const { storage } = require("./lib/commands/storage");
+const { teams } = require("./lib/commands/teams");
+const { users } = require("./lib/commands/users");
+
+program
+ .description(commandDescriptions['main'])
+ .version(version, "-v, --version")
+ .option("--verbose", "Show complete error log")
+ .option("--json", "Output in JSON format")
+ .on("option:json", () => {
+ cliConfig.json = true;
+ })
+ .on("option:verbose", () => {
+ cliConfig.verbose = true;
+ })
+ .showSuggestionAfterError()
+ .addCommand(login)
+ .addCommand(init)
+ .addCommand(deploy)
+ .addCommand(logout)
+ .addCommand(account)
+ .addCommand(avatars)
+ .addCommand(database)
+ .addCommand(functions)
+ .addCommand(health)
+ .addCommand(locale)
+ .addCommand(projects)
+ .addCommand(storage)
+ .addCommand(teams)
+ .addCommand(users)
+ .addCommand(client)
+ .parse(process.argv);
+
\ No newline at end of file
diff --git a/install.ps1 b/install.ps1
deleted file mode 100644
index 83afe53..0000000
--- a/install.ps1
+++ /dev/null
@@ -1,117 +0,0 @@
-##
-##
-##
-##
-##
-# Love open-source, dev-tooling and passionate about code as much as we do?
-# ---
-# We're always looking for awesome hackers like you to join our 100% remote team!
-# Check and see if you find any relevant position @ https://appwrite.io/company/careers
-# (and let us know you found this message...)
-
-# This script contains hidden JS code to allow better readability and syntax highlighting
-# You can use "View source" of this page to see the full script.
-
-# Appwrite CLI location
-$APPWRITE_INSTALL_DIR = Join-Path -Path $env:LOCALAPPDATA -ChildPath "Appwrite"
-
-# Appwrite CLI Executable name
-$APPWRITE_EXECUTABLE_NAME = "appwrite.ps1"
-
-# Appwrite executable file path
-$APPWRITE_EXECUTABLE_FILEPATH = Join-Path -Path $APPWRITE_INSTALL_DIR -ChildPath $APPWRITE_EXECUTABLE_NAME
-
-# Appwrite CLI image name
-$APPWRITE_CLI_IMAGE_NAME = "appwrite/cli"
-
-# Appwrite CLI image version
-$APPWRITE_CLI_IMAGE_VERSION = "0.13.1"
-
-$APPWRITE_EXECUTABLE_CONTENT = @"
-`$allowList = 'version', 'help', 'init', 'client' , 'account', 'avatars', 'database', 'functions', 'health', 'locale', 'storage', 'teams', 'users'
-if ( `$args.count -eq 0 ) {
- `$args += 'help'
-}
-
-if ( -not (`$allowList -contains `$args[0])) {
- Write-Host "Looks like a crazy hamster flipped a bit.`n`nUse appwrite help for a list of supported commands."
- exit 1
-}
-
-docker run -i --rm --volume appwrite-cli:/usr/local/code/app/.preferences/ --volume `$pwd``:/usr/local/code/files:rw --network host $APPWRITE_CLI_IMAGE_NAME`:$APPWRITE_CLI_IMAGE_VERSION (`$args | % {[uri]::EscapeUriString(`$_)})
-"@
-
-$USER_PATH_ENV_VAR = [Environment]::GetEnvironmentVariable("PATH", "User")
-
-function Greeting {
- Write-Host @"
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
-
-"@ -ForegroundColor red
- Write-Host "Welcome to the Appwrite CLI install shield."
-
-}
-
-function CheckSystemInfo {
- Write-Host "[1/4] Getting System Info ..."
- if ((Get-ExecutionPolicy) -gt 'RemoteSigned' -or (Get-ExecutionPolicy) -eq 'ByPass') {
- Write-Host "PowerShell requires an execution policy of 'RemoteSigned'."
- Write-Host "To make this change please run:"
- Write-Host "'Set-ExecutionPolicy RemoteSigned -scope CurrentUser'"
- break
- }
-}
-
-function PerformChecks {
-
- Write-Host "[2/4] Performing Checks ..."
-
- if (!(docker --version)) {
- throw "Docker could not be found. Please install docker for your OS from https://docs.docker.com/get-docker/ and try again."
- }
-
- if (!(docker ps)) {
- throw "The docker daemon is not operational. Make sure that docker is running and try again."
- }
-}
-
-function Install {
- Write-Host "[3/4] Starting installation ..."
-
- $out = (Invoke-Expression "docker pull $APPWRITE_CLI_IMAGE_NAME`:$APPWRITE_CLI_IMAGE_VERSION") | Out-String
-
- if ($out -NotMatch "Image is up to date|Downloaded newer image") {
- throw "Failed to fetch docker image. Exiting ..."
- }
-
- [void](New-Item -Path $APPWRITE_EXECUTABLE_FILEPATH -Value $APPWRITE_EXECUTABLE_CONTENT -ItemType File -Force)
-
- if ($USER_PATH_ENV_VAR -like '*Appwrite*') {
- Write-Host "Skipping to add Appwrite to User Path."
- }
- else {
- [System.Environment]::SetEnvironmentVariable("PATH", $USER_PATH_ENV_VAR + ";$APPWRITE_INSTALL_DIR", "User")
- }
-}
-
-function CleanUp {
- Write-Host "Cleaning up mess ..."
-}
-
-function InstallCompleted {
- Write-Host "[4/4] Finishing Installation ... "
- cleanup
- Write-Host "🤘 May the force be with you."
- Write-Host "To get started with Appwrite CLI, please visit https://appwrite.io/docs/command-line"
-}
-
-Greeting
-CheckSystemInfo
-PerformChecks
-Install
-InstallCompleted
diff --git a/install.sh b/install.sh
index 8b65efd..37b5aca 100644
--- a/install.sh
+++ b/install.sh
@@ -27,13 +27,12 @@ APPWRITE_EXECUTABLE_FILEPATH="$APPWRITE_INSTALL_DIR/$APPWRITE_EXECUTABLE_NAME"
APPWRITE_TEMP_NAME=temp-$(date +%s)
# Appwrite CLI image name
-APPWRITE_CLI_IMAGE_NAME=appwrite/cli
-
-# Appwrite CLI image version
-APPWRITE_CLI_IMAGE_VERSION=0.13.1
+GITHUB_REPOSITORY_NAME=appwrite/sdk-for-cli
# sudo is required to copy executable to APPWRITE_INSTALL_DIR for linux
USE_SUDO="false"
+OS=""
+ARCH=""
# Add some color to life
RED='\033[0;31m'
@@ -44,25 +43,28 @@ NC='\033[0m' # No Color
greeting() {
echo -e "${RED}"
cat << "EOF"
- _ _ _ ___ __ _____
- /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
- //_\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
- / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
- \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
- |_| |_|
-
+
+ _ _ _ ___ __ _____
+ /_\ _ __ _ ____ ___ __(_) |_ ___ / __\ / / \_ \
+ //_\\| '_ \| '_ \ \ /\ / / '__| | __/ _ \ / / / / / /\/
+ / _ \ |_) | |_) \ V V /| | | | || __/ / /___/ /___/\/ /_
+ \_/ \_/ .__/| .__/ \_/\_/ |_| |_|\__\___| \____/\____/\____/
+ |_| |_|
EOF
echo -e "${NC}\n"
- echo "🔥 Welcome to the Appwrite CLI install shield 🛡."
+ echo "🔥 Welcome to the Appwrite CLI install shield 🛡"
}
getSystemInfo() {
echo "[1/4] Getting System Info ..."
+
ARCH=$(uname -m)
case $ARCH in
- armv7*) ARCH="arm";;
- aarch64) ARCH="arm64";;
- x86_64) ARCH="amd64";;
+ i386|i686) ARCH="x64" ;;
+ x86_64) ARCH="x64";;
+ armv6*) ARCH="arm64" ;;
+ armv7*) ARCH="arm64" ;;
+ aarch64*) ARCH="arm64" ;;
esac
OS=$(echo `uname`|tr '[:upper:]' '[:lower:]')
@@ -92,67 +94,33 @@ printSuccess() {
printf "${GREEN}✅ Done ... ${NC}\n\n"
}
-performChecks() {
- echo "[2/4] Performing Checks ..."
+downloadBinary() {
+ echo "[2/4] Downloading executable for $OS ($ARCH) ..."
- # Check if docker is installed
- printf "${GREEN}🚦 Checking if docker is installed ... ${NC}\n"
- if ! command -v docker &> /dev/null; then
- printf "${RED}❌ Docker could not be found. Please install docker for your OS from https://docs.docker.com/get-docker/ and try again.${NC}\n"
+ printf "${GREEN}🚦 Fetching latest version ... ${NC}\n"
+ res=$(curl -L -s -H 'Accept: application/json' https://github.com/$GITHUB_REPOSITORY_NAME/releases/latest)
+ if [[ "$res" == *"error"* ]]; then
+ printf "${RED}❌ There was an error. Try again later.${NC} \n"
exit 1
fi
printSuccess
- # Check if the Docker Daemon is running
- printf "${GREEN}🏃 Checking if docker daemon is running ... ${NC}\n"
- rep=$(curl -s --unix-socket /var/run/docker.sock http://ping > /dev/null)
- status=$?
- if [ "$status" == "7" ]; then
- printf "${RED}❌ The docker daemon is not operational. Make sure that docker is running and try again.${NC} \n"
+ GITHUB_LATEST_VERSION=$( echo $res | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
+ GITHUB_FILE="appwrite-cli-${OS}-${ARCH}"
+ GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE"
+
+ printf "${GREEN}🚦 Downloading Appwrite CLI $GITHUB_LATEST_VERSION ... ${NC}\n"
+ res=$(curl -s $GITHUB_URL)
+ if [[ "$res" == *"Not Found"* ]]; then
+ printf "${RED}❌ Couldn't find executable for $OS ($ARCH). Please contact the Appwrite team ${NC} \n"
exit 1
fi
+ curl -L -o $APPWRITE_TEMP_NAME $GITHUB_URL
printSuccess
-
}
install() {
-
- echo "[3/4] Starting installation ..."
-
- # Fetch the Appwrite CLI Image.
- printf "${GREEN}🐳 Pulling docker image ... ${NC}\n"
- out=$(docker pull "$APPWRITE_CLI_IMAGE_NAME:$APPWRITE_CLI_IMAGE_VERSION")
- if [[ $out != *"Image is up to date"* ]] && [[ $out != *"Downloaded newer image"* ]]; then
- printf "${RED}❌ Failed to fetch docker image. Exiting ... ${NC}\n"
- exit 1
- fi
- printSuccess
-
- echo '#!/bin/bash
-
-allowList=(version help init client account avatars database functions health locale storage teams users)
-
-if [[ -z $1 ]]; then
- set -- "$@" help
-fi
-
-# Check if the command is in the allowList
-if [[ ! " ${allowList[@]} " =~ " ${1} " ]]; then
- printf "\nLooks like a crazy hamster 🐹 flipped a bit.\n\nUse appwrite help for a list of supported commands.\n"
- exit 1
-fi
-
-# https://stackoverflow.com/a/30655982/2299554
-for x in "${@}" ; do
- # try to figure out if quoting was required for the $x
- if [[ "$x" != "${x%[[:space:]]*}" ]]; then
- x="\""$x"\""
- fi
- x="${x// /%20}"
- _args=$_args" "$x
-done
-
-bash -c "docker run -i --rm --volume appwrite-cli:/usr/local/code/app/.preferences/ --volume \"$PWD\":/usr/local/code/files:rw --network host '$APPWRITE_CLI_IMAGE_NAME:$APPWRITE_CLI_IMAGE_VERSION' $_args" ' > $APPWRITE_TEMP_NAME
+ echo "[3/4] Installing ..."
printf "${GREEN}🚧 Setting Permissions ${NC}\n"
chmod +x $APPWRITE_TEMP_NAME
@@ -172,7 +140,7 @@ bash -c "docker run -i --rm --volume appwrite-cli:/usr/local/code/app/.preferenc
}
cleanup() {
- echo "🧹 Cleaning up mess ... "
+ printf "${GREEN}🧹 Cleaning up mess ... ${NC}\n"
rm $APPWRITE_TEMP_NAME
if [ $? -ne 0 ]; then
printf "${RED}❌ Failed to remove temporary file ... ${NC}\n"
@@ -192,6 +160,6 @@ installCompleted() {
# Installation Starts here
greeting
getSystemInfo
-performChecks
+downloadBinary
install
-installCompleted
+installCompleted
\ No newline at end of file
diff --git a/lib/client.js b/lib/client.js
new file mode 100644
index 0000000..7698ef9
--- /dev/null
+++ b/lib/client.js
@@ -0,0 +1,243 @@
+const os = require('os');
+const axios = require("axios");
+const FormData = require("form-data");
+const AppwriteException = require("./exception.js");
+const { globalConfig } = require("./config.js");
+
+class Client {
+ static CHUNK_SIZE = 5*1024*1024; // 5MB
+
+ constructor() {
+ this.endpoint = 'https://HOSTNAME/v1';
+ this.headers = {
+ 'content-type': '',
+ 'x-sdk-version': 'appwrite:cli:0.14.0',
+ 'User-Agent' : `AppwriteCLI/0.14.0 (${os.type()} ${os.version()}; ${os.arch()})`,
+ 'X-Appwrite-Response-Format' : '0.12.0',
+ };
+ }
+
+ /**
+ * Set Cookie
+ *
+ * Your cookie
+ *
+ * @param {string} cookie
+ *
+ * @return self
+ */
+ setCookie(cookie) {
+ this.addHeader("cookie", cookie);
+
+ return this;
+ }
+
+ /**
+ * Set Project
+ *
+ * Your project ID
+ *
+ * @param {string} project
+ *
+ * @return self
+ */
+ setProject(project) {
+ this.addHeader('X-Appwrite-Project', project);
+
+ return this;
+ }
+
+ /**
+ * Set Key
+ *
+ * Your secret API key
+ *
+ * @param {string} key
+ *
+ * @return self
+ */
+ setKey(key) {
+ this.addHeader('X-Appwrite-Key', key);
+
+ return this;
+ }
+
+ /**
+ * Set JWT
+ *
+ * Your secret JSON Web Token
+ *
+ * @param {string} jwt
+ *
+ * @return self
+ */
+ setJWT(jwt) {
+ this.addHeader('X-Appwrite-JWT', jwt);
+
+ return this;
+ }
+
+ /**
+ * Set Locale
+ *
+ * @param {string} locale
+ *
+ * @return self
+ */
+ setLocale(locale) {
+ this.addHeader('X-Appwrite-Locale', locale);
+
+ return this;
+ }
+
+ /**
+ * Set Mode
+ *
+ * @param {string} mode
+ *
+ * @return self
+ */
+ setMode(mode) {
+ this.addHeader('X-Appwrite-Mode', mode);
+
+ return this;
+ }
+
+ /**
+ * Set self signed.
+ *
+ * @param {bool} status
+ *
+ * @return this
+ */
+ setSelfSigned(status) {
+ this.selfSigned = status;
+
+ return this;
+ }
+
+ /**
+ * Set endpoint.
+ *
+ * @param {string} endpoint
+ *
+ * @return this
+ */
+ setEndpoint(endpoint) {
+ this.endpoint = endpoint;
+
+ return this;
+ }
+
+ /**
+ * @param {string} key
+ * @param {string} value
+ */
+ addHeader(key, value) {
+ this.headers[key.toLowerCase()] = value;
+
+ return this;
+ }
+
+ async call(
+ method,
+ path = "",
+ headers = {},
+ params = {},
+ responseType = "json"
+ ) {
+ if (this.selfSigned == true) {
+ // Allow self signed requests
+ process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
+ }
+
+ headers = Object.assign(this.headers, headers);
+
+ let contentType = headers["content-type"].toLowerCase();
+
+ let formData = null;
+
+ if (contentType.startsWith("multipart/form-data")) {
+ const form = new FormData();
+
+ let flatParams = Client.flatten(params);
+
+ for (const key in flatParams) {
+ form.append(key, flatParams[key]);
+ }
+
+ headers = {
+ ...headers,
+ ...form.getHeaders(),
+ };
+
+ formData = form;
+ }
+
+ let options = {
+ method: method.toUpperCase(),
+ url: this.endpoint + path,
+ params: method.toUpperCase() === "GET" ? params : {},
+ headers: headers,
+ data:
+ method.toUpperCase() === "GET" ||
+ contentType.startsWith("multipart/form-data")
+ ? formData
+ : params,
+ json: contentType.startsWith("application/json"),
+ responseType: responseType,
+ };
+ try {
+ let response = await axios(options);
+ if (response.headers["set-cookie"]) {
+ globalConfig.setCookie(response.headers["set-cookie"][0]);
+ }
+ return response.data;
+ } catch (error) {
+ if ("response" in error && error.response !== undefined) {
+ if (error.response && "data" in error.response) {
+ if (typeof error.response.data === "string") {
+ throw new AppwriteException(
+ error.response.data,
+ error.response.status,
+ error.response.data
+ );
+ } else {
+ throw new AppwriteException(
+ error.response.data.message,
+ error.response.status,
+ error.response.data
+ );
+ }
+ } else {
+ throw new AppwriteException(
+ error.response.statusText,
+ error.response.status,
+ error.response.data
+ );
+ }
+ } else {
+ throw new AppwriteException(error.message);
+ }
+ }
+ }
+
+ static flatten(data, prefix = "") {
+ let output = {};
+
+ for (const key in data) {
+ let value = data[key];
+ let finalKey = prefix ? prefix + "[" + key + "]" : key;
+
+ if (Array.isArray(value)) {
+ output = Object.assign(output, Client.flatten(value, finalKey)); // @todo: handle name collision here if needed
+ } else {
+ output[finalKey] = value;
+ }
+ }
+
+ return output;
+ }
+}
+
+module.exports = Client;
diff --git a/lib/commands/account.js b/lib/commands/account.js
new file mode 100644
index 0000000..5ac555d
--- /dev/null
+++ b/lib/commands/account.js
@@ -0,0 +1,785 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const account = new Command("account").description(commandDescriptions['account'])
+
+const accountGet = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreate = async ({ userId, email, password, name, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} userId */
+ /* @param {string} email */
+ /* @param {string} password */
+ /* @param {string} name */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof userId !== 'undefined') {
+ payload['userId'] = userId;
+ }
+
+ if (typeof email !== 'undefined') {
+ payload['email'] = email;
+ }
+
+ if (typeof password !== 'undefined') {
+ payload['password'] = password;
+ }
+
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountDelete = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdateEmail = async ({ email, password, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} email */
+ /* @param {string} password */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/email';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof email !== 'undefined') {
+ payload['email'] = email;
+ }
+
+ if (typeof password !== 'undefined') {
+ payload['password'] = password;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateJWT = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/jwt';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountGetLogs = async ({ limit, offset, parseOutput = true, sdk = undefined}) => {
+ /* @param {number} limit */
+ /* @param {number} offset */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/logs';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdateName = async ({ name, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} name */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/name';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdatePassword = async ({ password, oldPassword, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} password */
+ /* @param {string} oldPassword */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/password';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof password !== 'undefined') {
+ payload['password'] = password;
+ }
+
+ if (typeof oldPassword !== 'undefined') {
+ payload['oldPassword'] = oldPassword;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountGetPrefs = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/prefs';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdatePrefs = async ({ prefs, parseOutput = true, sdk = undefined}) => {
+ /* @param {object} prefs */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/prefs';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof prefs !== 'undefined') {
+ payload['prefs'] = prefs;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateRecovery = async ({ email, url, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} email */
+ /* @param {string} url */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/recovery';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof email !== 'undefined') {
+ payload['email'] = email;
+ }
+
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdateRecovery = async ({ userId, secret, password, passwordAgain, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} userId */
+ /* @param {string} secret */
+ /* @param {string} password */
+ /* @param {string} passwordAgain */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/recovery';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof userId !== 'undefined') {
+ payload['userId'] = userId;
+ }
+
+ if (typeof secret !== 'undefined') {
+ payload['secret'] = secret;
+ }
+
+ if (typeof password !== 'undefined') {
+ payload['password'] = password;
+ }
+
+ if (typeof passwordAgain !== 'undefined') {
+ payload['passwordAgain'] = passwordAgain;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountGetSessions = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateSession = async ({ email, password, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} email */
+ /* @param {string} password */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof email !== 'undefined') {
+ payload['email'] = email;
+ }
+
+ if (typeof password !== 'undefined') {
+ payload['password'] = password;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountDeleteSessions = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateAnonymousSession = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/anonymous';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateMagicURLSession = async ({ userId, email, url, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} userId */
+ /* @param {string} email */
+ /* @param {string} url */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/magic-url';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof userId !== 'undefined') {
+ payload['userId'] = userId;
+ }
+
+ if (typeof email !== 'undefined') {
+ payload['email'] = email;
+ }
+
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdateMagicURLSession = async ({ userId, secret, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} userId */
+ /* @param {string} secret */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/magic-url';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof userId !== 'undefined') {
+ payload['userId'] = userId;
+ }
+
+ if (typeof secret !== 'undefined') {
+ payload['secret'] = secret;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateOAuth2Session = async ({ provider, success, failure, scopes, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} provider */
+ /* @param {string} success */
+ /* @param {string} failure */
+ /* @param {string[]} scopes */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/oauth2/{provider}'.replace('{provider}', provider);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof success !== 'undefined') {
+ payload['success'] = success;
+ }
+ if (typeof failure !== 'undefined') {
+ payload['failure'] = failure;
+ }
+ if (typeof scopes !== 'undefined') {
+ payload['scopes'] = scopes;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountGetSession = async ({ sessionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} sessionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/{sessionId}'.replace('{sessionId}', sessionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdateSession = async ({ sessionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} sessionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/{sessionId}'.replace('{sessionId}', sessionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountDeleteSession = async ({ sessionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} sessionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/sessions/{sessionId}'.replace('{sessionId}', sessionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountCreateVerification = async ({ url, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} url */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/verification';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const accountUpdateVerification = async ({ userId, secret, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} userId */
+ /* @param {string} secret */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/account/verification';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof userId !== 'undefined') {
+ payload['userId'] = userId;
+ }
+
+ if (typeof secret !== 'undefined') {
+ payload['secret'] = secret;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+
+account
+ .command(`get`)
+ .description(`Get currently logged in user data as JSON object.`)
+ .action(actionRunner(accountGet))
+
+account
+ .command(`create`)
+ .description(`Use this endpoint to allow a new user to register a new account in your project. After the user registration completes successfully, you can use the [/account/verfication](/docs/client/account#accountCreateVerification) route to start verifying the user email address. To allow the new user to login to their new account, you need to create a new [account session](/docs/client/account#accountCreateSession).`)
+ .requiredOption(`--userId `, `Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
+ .requiredOption(`--email `, `User email.`)
+ .requiredOption(`--password `, `User password. Must be at least 8 chars.`)
+ .option(`--name `, `User name. Max length: 128 chars.`)
+ .action(actionRunner(accountCreate))
+
+account
+ .command(`delete`)
+ .description(`Delete a currently logged in user account. Behind the scene, the user record is not deleted but permanently blocked from any access. This is done to avoid deleted accounts being overtaken by new users with the same email address. Any user-related resources like documents or storage files should be deleted separately.`)
+ .action(actionRunner(accountDelete))
+
+account
+ .command(`updateEmail`)
+ .description(`Update currently logged in user account email address. After changing user address, the user confirmation status will get reset. A new confirmation email is not sent automatically however you can use the send confirmation email endpoint again to send the confirmation email. For security measures, user password is required to complete this request. This endpoint can also be used to convert an anonymous account to a normal one, by passing an email address and a new password. `)
+ .requiredOption(`--email `, `User email.`)
+ .requiredOption(`--password `, `User password. Must be at least 8 chars.`)
+ .action(actionRunner(accountUpdateEmail))
+
+account
+ .command(`createJWT`)
+ .description(`Use this endpoint to create a JSON Web Token. You can use the resulting JWT to authenticate on behalf of the current user when working with the Appwrite server-side API and SDKs. The JWT secret is valid for 15 minutes from its creation and will be invalid if the user will logout in that time frame.`)
+ .action(actionRunner(accountCreateJWT))
+
+account
+ .command(`getLogs`)
+ .description(`Get currently logged in user list of latest security activity logs. Each log returns user IP address, location and date and time of log.`)
+ .option(`--limit `, `Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .action(actionRunner(accountGetLogs))
+
+account
+ .command(`updateName`)
+ .description(`Update currently logged in user account name.`)
+ .requiredOption(`--name `, `User name. Max length: 128 chars.`)
+ .action(actionRunner(accountUpdateName))
+
+account
+ .command(`updatePassword`)
+ .description(`Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth and Team Invites, oldPassword is optional.`)
+ .requiredOption(`--password `, `New user password. Must be at least 8 chars.`)
+ .option(`--oldPassword `, `Current user password. Must be at least 8 chars.`)
+ .action(actionRunner(accountUpdatePassword))
+
+account
+ .command(`getPrefs`)
+ .description(`Get currently logged in user preferences as a key-value object.`)
+ .action(actionRunner(accountGetPrefs))
+
+account
+ .command(`updatePrefs`)
+ .description(`Update currently logged in user account preferences. The object you pass is stored as is, and replaces any previous value. The maximum allowed prefs size is 64kB and throws error if exceeded.`)
+ .requiredOption(`--prefs `, `Prefs key-value JSON object.`)
+ .action(actionRunner(accountUpdatePrefs))
+
+account
+ .command(`createRecovery`)
+ .description(`Sends the user an email with a temporary secret key for password reset. When the user clicks the confirmation link he is redirected back to your app password reset URL with the secret key and email address values attached to the URL query string. Use the query string params to submit a request to the [PUT /account/recovery](/docs/client/account#accountUpdateRecovery) endpoint to complete the process. The verification link sent to the user's email address is valid for 1 hour.`)
+ .requiredOption(`--email `, `User email.`)
+ .requiredOption(`--url `, `URL to redirect the user back to your app from the recovery email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.`)
+ .action(actionRunner(accountCreateRecovery))
+
+account
+ .command(`updateRecovery`)
+ .description(`Use this endpoint to complete the user account password reset. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST /account/recovery](/docs/client/account#accountCreateRecovery) endpoint. Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.`)
+ .requiredOption(`--userId `, `User ID.`)
+ .requiredOption(`--secret `, `Valid reset token.`)
+ .requiredOption(`--password `, `New user password. Must be at least 8 chars.`)
+ .requiredOption(`--passwordAgain `, `Repeat new user password. Must be at least 8 chars.`)
+ .action(actionRunner(accountUpdateRecovery))
+
+account
+ .command(`getSessions`)
+ .description(`Get currently logged in user list of active sessions across different devices.`)
+ .action(actionRunner(accountGetSessions))
+
+account
+ .command(`createSession`)
+ .description(`Allow the user to login into their account by providing a valid email and password combination. This route will create a new session for the user.`)
+ .requiredOption(`--email `, `User email.`)
+ .requiredOption(`--password `, `User password. Must be at least 8 chars.`)
+ .action(actionRunner(accountCreateSession))
+
+account
+ .command(`deleteSessions`)
+ .description(`Delete all sessions from the user account and remove any sessions cookies from the end client.`)
+ .action(actionRunner(accountDeleteSessions))
+
+account
+ .command(`createAnonymousSession`)
+ .description(`Use this endpoint to allow a new user to register an anonymous account in your project. This route will also create a new session for the user. To allow the new user to convert an anonymous account to a normal account, you need to update its [email and password](/docs/client/account#accountUpdateEmail) or create an [OAuth2 session](/docs/client/account#accountCreateOAuth2Session).`)
+ .action(actionRunner(accountCreateAnonymousSession))
+
+account
+ .command(`createMagicURLSession`)
+ .description(`Sends the user an email with a secret key for creating a session. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [PUT /account/sessions/magic-url](/docs/client/account#accountUpdateMagicURLSession) endpoint to complete the login process. The link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.`)
+ .requiredOption(`--userId `, `Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
+ .requiredOption(`--email `, `User email.`)
+ .option(`--url `, `URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.`)
+ .action(actionRunner(accountCreateMagicURLSession))
+
+account
+ .command(`updateMagicURLSession`)
+ .description(`Use this endpoint to complete creating the session with the Magic URL. Both the **userId** and **secret** arguments will be passed as query parameters to the redirect URL you have provided when sending your request to the [POST /account/sessions/magic-url](/docs/client/account#accountCreateMagicURLSession) endpoint. Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface.`)
+ .requiredOption(`--userId `, `User ID.`)
+ .requiredOption(`--secret `, `Valid verification token.`)
+ .action(actionRunner(accountUpdateMagicURLSession))
+
+account
+ .command(`createOAuth2Session`)
+ .description(`Allow the user to login to their account using the OAuth2 provider of their choice. Each OAuth2 provider should be enabled from the Appwrite console first. Use the success and failure arguments to provide a redirect URL's back to your app when login is completed. If there is already an active session, the new session will be attached to the logged-in account. If there are no active sessions, the server will attempt to look for a user with the same email address as the email received from the OAuth2 provider and attach the new session to the existing user. If no matching user is found - the server will create a new user.. `)
+ .requiredOption(`--provider `, `OAuth2 Provider. Currently, supported providers are: amazon, apple, bitbucket, bitly, box, discord, dropbox, facebook, github, gitlab, google, linkedin, microsoft, notion, paypal, paypalSandbox, salesforce, slack, spotify, tradeshift, tradeshiftBox, twitch, vk, yahoo, yammer, yandex, wordpress, stripe.`)
+ .option(`--success `, `URL to redirect back to your app after a successful login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.`)
+ .option(`--failure `, `URL to redirect back to your app after a failed login attempt. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.`)
+ .option(`--scopes `, `A list of custom OAuth2 scopes. Check each provider internal docs for a list of supported scopes.`)
+ .action(actionRunner(accountCreateOAuth2Session))
+
+account
+ .command(`getSession`)
+ .description(`Use this endpoint to get a logged in user's session using a Session ID. Inputting 'current' will return the current session being used.`)
+ .requiredOption(`--sessionId `, `Session ID. Use the string 'current' to get the current device session.`)
+ .action(actionRunner(accountGetSession))
+
+account
+ .command(`updateSession`)
+ .description(``)
+ .requiredOption(`--sessionId `, `Session ID. Use the string 'current' to update the current device session.`)
+ .action(actionRunner(accountUpdateSession))
+
+account
+ .command(`deleteSession`)
+ .description(`Use this endpoint to log out the currently logged in user from all their account sessions across all of their different devices. When using the Session ID argument, only the unique session ID provided is deleted. `)
+ .requiredOption(`--sessionId `, `Session ID. Use the string 'current' to delete the current device session.`)
+ .action(actionRunner(accountDeleteSession))
+
+account
+ .command(`createVerification`)
+ .description(`Use this endpoint to send a verification message to your user email address to confirm they are the valid owners of that address. Both the **userId** and **secret** arguments will be passed as query parameters to the URL you have provided to be attached to the verification email. The provided URL should redirect the user back to your app and allow you to complete the verification process by verifying both the **userId** and **secret** parameters. Learn more about how to [complete the verification process](/docs/client/account#accountUpdateVerification). The verification link sent to the user's email address is valid for 7 days. Please note that in order to avoid a [Redirect Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md), the only valid redirect URLs are the ones from domains you have set when adding your platforms in the console interface. `)
+ .requiredOption(`--url `, `URL to redirect the user back to your app from the verification email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.`)
+ .action(actionRunner(accountCreateVerification))
+
+account
+ .command(`updateVerification`)
+ .description(`Use this endpoint to complete the user email verification process. Use both the **userId** and **secret** parameters that were attached to your app URL to verify the user email ownership. If confirmed this route will return a 200 status code.`)
+ .requiredOption(`--userId `, `User ID.`)
+ .requiredOption(`--secret `, `Valid verification token.`)
+ .action(actionRunner(accountUpdateVerification))
+
+
+module.exports = {
+ account,
+ accountGet,
+ accountCreate,
+ accountDelete,
+ accountUpdateEmail,
+ accountCreateJWT,
+ accountGetLogs,
+ accountUpdateName,
+ accountUpdatePassword,
+ accountGetPrefs,
+ accountUpdatePrefs,
+ accountCreateRecovery,
+ accountUpdateRecovery,
+ accountGetSessions,
+ accountCreateSession,
+ accountDeleteSessions,
+ accountCreateAnonymousSession,
+ accountCreateMagicURLSession,
+ accountUpdateMagicURLSession,
+ accountCreateOAuth2Session,
+ accountGetSession,
+ accountUpdateSession,
+ accountDeleteSession,
+ accountCreateVerification,
+ accountUpdateVerification
+};
\ No newline at end of file
diff --git a/lib/commands/avatars.js b/lib/commands/avatars.js
new file mode 100644
index 0000000..fe15eca
--- /dev/null
+++ b/lib/commands/avatars.js
@@ -0,0 +1,349 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const avatars = new Command("avatars").description(commandDescriptions['avatars'])
+
+const avatarsGetBrowser = async ({ code, width, height, quality, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} code */
+ /* @param {number} width */
+ /* @param {number} height */
+ /* @param {number} quality */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/browsers/{code}'.replace('{code}', code);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof width !== 'undefined') {
+ payload['width'] = width;
+ }
+ if (typeof height !== 'undefined') {
+ payload['height'] = height;
+ }
+ if (typeof quality !== 'undefined') {
+ payload['quality'] = quality;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+const avatarsGetCreditCard = async ({ code, width, height, quality, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} code */
+ /* @param {number} width */
+ /* @param {number} height */
+ /* @param {number} quality */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/credit-cards/{code}'.replace('{code}', code);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof width !== 'undefined') {
+ payload['width'] = width;
+ }
+ if (typeof height !== 'undefined') {
+ payload['height'] = height;
+ }
+ if (typeof quality !== 'undefined') {
+ payload['quality'] = quality;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+const avatarsGetFavicon = async ({ url, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} url */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/favicon';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+const avatarsGetFlag = async ({ code, width, height, quality, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} code */
+ /* @param {number} width */
+ /* @param {number} height */
+ /* @param {number} quality */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/flags/{code}'.replace('{code}', code);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof width !== 'undefined') {
+ payload['width'] = width;
+ }
+ if (typeof height !== 'undefined') {
+ payload['height'] = height;
+ }
+ if (typeof quality !== 'undefined') {
+ payload['quality'] = quality;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+const avatarsGetImage = async ({ url, width, height, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} url */
+ /* @param {number} width */
+ /* @param {number} height */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/image';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+ if (typeof width !== 'undefined') {
+ payload['width'] = width;
+ }
+ if (typeof height !== 'undefined') {
+ payload['height'] = height;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+const avatarsGetInitials = async ({ name, width, height, color, background, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} name */
+ /* @param {number} width */
+ /* @param {number} height */
+ /* @param {string} color */
+ /* @param {string} background */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/initials';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+ if (typeof width !== 'undefined') {
+ payload['width'] = width;
+ }
+ if (typeof height !== 'undefined') {
+ payload['height'] = height;
+ }
+ if (typeof color !== 'undefined') {
+ payload['color'] = color;
+ }
+ if (typeof background !== 'undefined') {
+ payload['background'] = background;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+const avatarsGetQR = async ({ text, size, margin, download, parseOutput = true, sdk = undefined, destination}) => {
+ /* @param {string} text */
+ /* @param {number} size */
+ /* @param {number} margin */
+ /* @param {boolean} download */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/avatars/qr';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof text !== 'undefined') {
+ payload['text'] = text;
+ }
+ if (typeof size !== 'undefined') {
+ payload['size'] = size;
+ }
+ if (typeof margin !== 'undefined') {
+ payload['margin'] = margin;
+ }
+ if (typeof download !== 'undefined') {
+ payload['download'] = download;
+ }
+ payload['project'] = localConfig.getProject().projectId
+ payload['key'] = globalConfig.getKey();
+ const queryParams = new URLSearchParams(payload);
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
+
+ const response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload, 'arraybuffer');
+
+ fs.writeFileSync(destination, response);
+
+ if (parseOutput) {
+ log(`File stored in ${destination}`)
+ success()
+ }
+}
+
+
+avatars
+ .command(`getBrowser`)
+ .description(`You can use this endpoint to show different browser icons to your users. The code argument receives the browser code as it appears in your user /account/sessions endpoint. Use width, height and quality arguments to change the output settings.`)
+ .requiredOption(`--code `, `Browser Code.`)
+ .option(`--width `, `Image width. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--height `, `Image height. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--quality `, `Image quality. Pass an integer between 0 to 100. Defaults to 100.`, parseInteger)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetBrowser))
+
+avatars
+ .command(`getCreditCard`)
+ .description(`The credit card endpoint will return you the icon of the credit card provider you need. Use width, height and quality arguments to change the output settings.`)
+ .requiredOption(`--code `, `Credit Card Code. Possible values: amex, argencard, cabal, censosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.`)
+ .option(`--width `, `Image width. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--height `, `Image height. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--quality `, `Image quality. Pass an integer between 0 to 100. Defaults to 100.`, parseInteger)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetCreditCard))
+
+avatars
+ .command(`getFavicon`)
+ .description(`Use this endpoint to fetch the favorite icon (AKA favicon) of any remote website URL. `)
+ .requiredOption(`--url `, `Website URL which you want to fetch the favicon from.`)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetFavicon))
+
+avatars
+ .command(`getFlag`)
+ .description(`You can use this endpoint to show different country flags icons to your users. The code argument receives the 2 letter country code. Use width, height and quality arguments to change the output settings.`)
+ .requiredOption(`--code `, `Country Code. ISO Alpha-2 country code format.`)
+ .option(`--width `, `Image width. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--height `, `Image height. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--quality `, `Image quality. Pass an integer between 0 to 100. Defaults to 100.`, parseInteger)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetFlag))
+
+avatars
+ .command(`getImage`)
+ .description(`Use this endpoint to fetch a remote image URL and crop it to any image size you want. This endpoint is very useful if you need to crop and display remote images in your app or in case you want to make sure a 3rd party image is properly served using a TLS protocol.`)
+ .requiredOption(`--url `, `Image URL which you want to crop.`)
+ .option(`--width `, `Resize preview image width, Pass an integer between 0 to 2000.`, parseInteger)
+ .option(`--height `, `Resize preview image height, Pass an integer between 0 to 2000.`, parseInteger)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetImage))
+
+avatars
+ .command(`getInitials`)
+ .description(`Use this endpoint to show your user initials avatar icon on your website or app. By default, this route will try to print your logged-in user name or email initials. You can also overwrite the user name if you pass the 'name' parameter. If no name is given and no user is logged, an empty avatar will be returned. You can use the color and background params to change the avatar colors. By default, a random theme will be selected. The random theme will persist for the user's initials when reloading the same theme will always return for the same initials.`)
+ .option(`--name `, `Full Name. When empty, current user name or email will be used. Max length: 128 chars.`)
+ .option(`--width `, `Image width. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--height `, `Image height. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
+ .option(`--color `, `Changes text color. By default a random color will be picked and stay will persistent to the given name.`)
+ .option(`--background `, `Changes background color. By default a random color will be picked and stay will persistent to the given name.`)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetInitials))
+
+avatars
+ .command(`getQR`)
+ .description(`Converts a given plain text to a QR code image. You can use the query parameters to change the size and style of the resulting image.`)
+ .requiredOption(`--text `, `Plain text to be converted to QR code image.`)
+ .option(`--size `, `QR code size. Pass an integer between 0 to 1000. Defaults to 400.`, parseInteger)
+ .option(`--margin `, `Margin from edge. Pass an integer between 0 to 10. Defaults to 1.`, parseInteger)
+ .option(`--download `, `Return resulting image with 'Content-Disposition: attachment ' headers for the browser to start downloading it. Pass 0 for no header, or 1 for otherwise. Default value is set to 0.`, parseBool)
+ .requiredOption(`--destination `, `output file path.`)
+ .action(actionRunner(avatarsGetQR))
+
+
+module.exports = {
+ avatars,
+ avatarsGetBrowser,
+ avatarsGetCreditCard,
+ avatarsGetFavicon,
+ avatarsGetFlag,
+ avatarsGetImage,
+ avatarsGetInitials,
+ avatarsGetQR
+};
\ No newline at end of file
diff --git a/lib/commands/database.js b/lib/commands/database.js
new file mode 100644
index 0000000..ebd4ceb
--- /dev/null
+++ b/lib/commands/database.js
@@ -0,0 +1,1238 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const database = new Command("database").description(commandDescriptions['database'])
+
+const databaseListCollections = async ({ search, limit, offset, cursor, cursorDirection, orderType, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} search */
+ /* @param {number} limit */
+ /* @param {number} offset */
+ /* @param {string} cursor */
+ /* @param {string} cursorDirection */
+ /* @param {string} orderType */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof search !== 'undefined') {
+ payload['search'] = search;
+ }
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ if (typeof cursor !== 'undefined') {
+ payload['cursor'] = cursor;
+ }
+ if (typeof cursorDirection !== 'undefined') {
+ payload['cursorDirection'] = cursorDirection;
+ }
+ if (typeof orderType !== 'undefined') {
+ payload['orderType'] = orderType;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateCollection = async ({ collectionId, name, permission, read, write, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} name */
+ /* @param {string} permission */
+ /* @param {string[]} read */
+ /* @param {string[]} write */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof collectionId !== 'undefined') {
+ payload['collectionId'] = collectionId;
+ }
+
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof permission !== 'undefined') {
+ payload['permission'] = permission;
+ }
+
+ if (typeof read !== 'undefined') {
+ payload['read'] = read;
+ }
+
+ if (typeof write !== 'undefined') {
+ payload['write'] = write;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseGetCollection = async ({ collectionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}'.replace('{collectionId}', collectionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseUpdateCollection = async ({ collectionId, name, permission, read, write, enabled, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} name */
+ /* @param {string} permission */
+ /* @param {string[]} read */
+ /* @param {string[]} write */
+ /* @param {boolean} enabled */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof permission !== 'undefined') {
+ payload['permission'] = permission;
+ }
+
+ if (typeof read !== 'undefined') {
+ payload['read'] = read;
+ }
+
+ if (typeof write !== 'undefined') {
+ payload['write'] = write;
+ }
+
+ if (typeof enabled !== 'undefined') {
+ payload['enabled'] = enabled;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseDeleteCollection = async ({ collectionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}'.replace('{collectionId}', collectionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseListAttributes = async ({ collectionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes'.replace('{collectionId}', collectionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateBooleanAttribute = async ({ collectionId, key, required, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {boolean} required */
+ /* @param {boolean} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/boolean'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateEmailAttribute = async ({ collectionId, key, required, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {boolean} required */
+ /* @param {string} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/email'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateEnumAttribute = async ({ collectionId, key, elements, required, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {string[]} elements */
+ /* @param {boolean} required */
+ /* @param {string} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/enum'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof elements !== 'undefined') {
+ payload['elements'] = elements;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateFloatAttribute = async ({ collectionId, key, required, min, max, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {boolean} required */
+ /* @param {number} min */
+ /* @param {number} max */
+ /* @param {number} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/float'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof min !== 'undefined') {
+ payload['min'] = min;
+ }
+
+ if (typeof max !== 'undefined') {
+ payload['max'] = max;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateIntegerAttribute = async ({ collectionId, key, required, min, max, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {boolean} required */
+ /* @param {number} min */
+ /* @param {number} max */
+ /* @param {number} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/integer'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof min !== 'undefined') {
+ payload['min'] = min;
+ }
+
+ if (typeof max !== 'undefined') {
+ payload['max'] = max;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateIpAttribute = async ({ collectionId, key, required, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {boolean} required */
+ /* @param {string} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/ip'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateStringAttribute = async ({ collectionId, key, size, required, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {number} size */
+ /* @param {boolean} required */
+ /* @param {string} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/string'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof size !== 'undefined') {
+ payload['size'] = size;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateUrlAttribute = async ({ collectionId, key, required, xdefault, array, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {boolean} required */
+ /* @param {string} xdefault */
+ /* @param {boolean} array */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/url'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof required !== 'undefined') {
+ payload['required'] = required;
+ }
+
+ if (typeof xdefault !== 'undefined') {
+ payload['default'] = xdefault;
+ }
+
+ if (typeof array !== 'undefined') {
+ payload['array'] = array;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseGetAttribute = async ({ collectionId, key, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/{key}'.replace('{collectionId}', collectionId).replace('{key}', key);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseDeleteAttribute = async ({ collectionId, key, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/attributes/{key}'.replace('{collectionId}', collectionId).replace('{key}', key);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseListDocuments = async ({ collectionId, queries, limit, offset, cursor, cursorDirection, orderAttributes, orderTypes, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string[]} queries */
+ /* @param {number} limit */
+ /* @param {number} offset */
+ /* @param {string} cursor */
+ /* @param {string} cursorDirection */
+ /* @param {string[]} orderAttributes */
+ /* @param {string[]} orderTypes */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/documents'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof queries !== 'undefined') {
+ payload['queries'] = queries;
+ }
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ if (typeof cursor !== 'undefined') {
+ payload['cursor'] = cursor;
+ }
+ if (typeof cursorDirection !== 'undefined') {
+ payload['cursorDirection'] = cursorDirection;
+ }
+ if (typeof orderAttributes !== 'undefined') {
+ payload['orderAttributes'] = orderAttributes;
+ }
+ if (typeof orderTypes !== 'undefined') {
+ payload['orderTypes'] = orderTypes;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateDocument = async ({ collectionId, documentId, data, read, write, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} documentId */
+ /* @param {object} data */
+ /* @param {string[]} read */
+ /* @param {string[]} write */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/documents'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof documentId !== 'undefined') {
+ payload['documentId'] = documentId;
+ }
+
+ if (typeof data !== 'undefined') {
+ payload['data'] = data;
+ }
+
+ if (typeof read !== 'undefined') {
+ payload['read'] = read;
+ }
+
+ if (typeof write !== 'undefined') {
+ payload['write'] = write;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseGetDocument = async ({ collectionId, documentId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} documentId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}', collectionId).replace('{documentId}', documentId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseUpdateDocument = async ({ collectionId, documentId, data, read, write, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} documentId */
+ /* @param {object} data */
+ /* @param {string[]} read */
+ /* @param {string[]} write */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}', collectionId).replace('{documentId}', documentId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof data !== 'undefined') {
+ payload['data'] = data;
+ }
+
+ if (typeof read !== 'undefined') {
+ payload['read'] = read;
+ }
+
+ if (typeof write !== 'undefined') {
+ payload['write'] = write;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseDeleteDocument = async ({ collectionId, documentId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} documentId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/documents/{documentId}'.replace('{collectionId}', collectionId).replace('{documentId}', documentId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseListDocumentLogs = async ({ collectionId, documentId, limit, offset, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} documentId */
+ /* @param {number} limit */
+ /* @param {number} offset */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/documents/{documentId}/logs'.replace('{collectionId}', collectionId).replace('{documentId}', documentId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseListIndexes = async ({ collectionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/indexes'.replace('{collectionId}', collectionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseCreateIndex = async ({ collectionId, key, type, attributes, orders, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+ /* @param {string} type */
+ /* @param {string[]} attributes */
+ /* @param {string[]} orders */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/indexes'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof type !== 'undefined') {
+ payload['type'] = type;
+ }
+
+ if (typeof attributes !== 'undefined') {
+ payload['attributes'] = attributes;
+ }
+
+ if (typeof orders !== 'undefined') {
+ payload['orders'] = orders;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseGetIndex = async ({ collectionId, key, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/indexes/{key}'.replace('{collectionId}', collectionId).replace('{key}', key);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseDeleteIndex = async ({ collectionId, key, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} key */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/indexes/{key}'.replace('{collectionId}', collectionId).replace('{key}', key);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseListCollectionLogs = async ({ collectionId, limit, offset, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {number} limit */
+ /* @param {number} offset */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/collections/{collectionId}/logs'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseGetUsage = async ({ range, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} range */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/usage';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof range !== 'undefined') {
+ payload['range'] = range;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const databaseGetCollectionUsage = async ({ collectionId, range, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} collectionId */
+ /* @param {string} range */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/database/{collectionId}/usage'.replace('{collectionId}', collectionId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof range !== 'undefined') {
+ payload['range'] = range;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+
+database
+ .command(`listCollections`)
+ .description(`Get a list of all the user collections. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's collections. [Learn more about different API modes](/docs/admin).`)
+ .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`)
+ .option(`--limit `, `Maximum number of collection to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .option(`--cursor `, `ID of the collection used as the starting point for the query, excluding the collection itself. Should be used for efficient pagination when working with large sets of data.`)
+ .option(`--cursorDirection `, `Direction of the cursor.`)
+ .option(`--orderType `, `Order result by ASC or DESC order.`)
+ .action(actionRunner(databaseListCollections))
+
+database
+ .command(`createCollection`)
+ .description(`Create a new Collection.`)
+ .requiredOption(`--collectionId `, `Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
+ .requiredOption(`--name `, `Collection name. Max length: 128 chars.`)
+ .requiredOption(`--permission `, `Permissions type model to use for reading documents in this collection. You can use collection-level permission set once on the collection using the 'read' and 'write' params, or you can set document-level permission where each document read and write params will decide who has access to read and write to each document individually. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .requiredOption(`--read `, `An array of strings with read permissions. By default no user is granted with any read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .requiredOption(`--write `, `An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .action(actionRunner(databaseCreateCollection))
+
+database
+ .command(`getCollection`)
+ .description(`Get a collection by its unique ID. This endpoint response returns a JSON object with the collection metadata.`)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .action(actionRunner(databaseGetCollection))
+
+database
+ .command(`updateCollection`)
+ .description(`Update a collection by its unique ID.`)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .requiredOption(`--name `, `Collection name. Max length: 128 chars.`)
+ .requiredOption(`--permission `, `Permissions type model to use for reading documents in this collection. You can use collection-level permission set once on the collection using the 'read' and 'write' params, or you can set document-level permission where each document read and write params will decide who has access to read and write to each document individually. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .option(`--read `, `An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .option(`--write `, `An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .option(`--enabled `, `Is collection enabled?`, parseBool)
+ .action(actionRunner(databaseUpdateCollection))
+
+database
+ .command(`deleteCollection`)
+ .description(`Delete a collection by its unique ID. Only users with write permissions have access to delete this resource.`)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .action(actionRunner(databaseDeleteCollection))
+
+database
+ .command(`listAttributes`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .action(actionRunner(databaseListAttributes))
+
+database
+ .command(`createBooleanAttribute`)
+ .description(`Create a boolean attribute. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`, parseBool)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateBooleanAttribute))
+
+database
+ .command(`createEmailAttribute`)
+ .description(`Create an email attribute. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateEmailAttribute))
+
+database
+ .command(`createEnumAttribute`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--elements `, `Array of elements in enumerated type. Uses length of longest element to determine size.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateEnumAttribute))
+
+database
+ .command(`createFloatAttribute`)
+ .description(`Create a float attribute. Optionally, minimum and maximum values can be provided. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--min `, `Minimum value to enforce on new documents`, parseInteger)
+ .option(`--max `, `Maximum value to enforce on new documents`, parseInteger)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`, parseInteger)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateFloatAttribute))
+
+database
+ .command(`createIntegerAttribute`)
+ .description(`Create an integer attribute. Optionally, minimum and maximum values can be provided. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--min `, `Minimum value to enforce on new documents`, parseInteger)
+ .option(`--max `, `Maximum value to enforce on new documents`, parseInteger)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`, parseInteger)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateIntegerAttribute))
+
+database
+ .command(`createIpAttribute`)
+ .description(`Create IP address attribute. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateIpAttribute))
+
+database
+ .command(`createStringAttribute`)
+ .description(`Create a string attribute. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--size `, `Attribute size for text attributes, in number of characters.`, parseInteger)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateStringAttribute))
+
+database
+ .command(`createUrlAttribute`)
+ .description(`Create a URL attribute. `)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .requiredOption(`--required `, `Is attribute required?`, parseBool)
+ .option(`--xdefault `, `Default value for attribute when not provided. Cannot be set when attribute is required.`)
+ .option(`--array `, `Is attribute an array?`, parseBool)
+ .action(actionRunner(databaseCreateUrlAttribute))
+
+database
+ .command(`getAttribute`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .action(actionRunner(databaseGetAttribute))
+
+database
+ .command(`deleteAttribute`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Attribute Key.`)
+ .action(actionRunner(databaseDeleteAttribute))
+
+database
+ .command(`listDocuments`)
+ .description(`Get a list of all the user documents. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's documents. [Learn more about different API modes](/docs/admin).`)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .option(`--queries `, `Array of query strings.`)
+ .option(`--limit `, `Maximum number of documents to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .option(`--cursor `, `ID of the document used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
+ .option(`--cursorDirection `, `Direction of the cursor.`)
+ .option(`--orderAttributes `, `Array of attributes used to sort results.`)
+ .option(`--orderTypes `, `Array of order directions for sorting attribtues. Possible values are DESC for descending order, or ASC for ascending order.`)
+ .action(actionRunner(databaseListDocuments))
+
+database
+ .command(`createDocument`)
+ .description(`Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](/docs/server/database#databaseCreateCollection) API or directly from your database console.`)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection). Make sure to define attributes before creating documents.`)
+ .requiredOption(`--documentId `, `Document ID. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
+ .requiredOption(`--data `, `Document data as JSON object.`)
+ .option(`--read `, `An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .option(`--write `, `An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .action(actionRunner(databaseCreateDocument))
+
+database
+ .command(`getDocument`)
+ .description(`Get a document by its unique ID. This endpoint response returns a JSON object with the document data.`)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--documentId `, `Document ID.`)
+ .action(actionRunner(databaseGetDocument))
+
+database
+ .command(`updateDocument`)
+ .description(`Update a document by its unique ID. Using the patch method you can pass only specific fields that will get updated.`)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .requiredOption(`--documentId `, `Document ID.`)
+ .requiredOption(`--data `, `Document data as JSON object.`)
+ .option(`--read `, `An array of strings with read permissions. By default inherits the existing read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .option(`--write `, `An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .action(actionRunner(databaseUpdateDocument))
+
+database
+ .command(`deleteDocument`)
+ .description(`Delete a document by its unique ID. This endpoint deletes only the parent documents, its attributes and relations to other documents. Child documents **will not** be deleted.`)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--documentId `, `Document ID.`)
+ .action(actionRunner(databaseDeleteDocument))
+
+database
+ .command(`listDocumentLogs`)
+ .description(`Get the document activity logs list by its unique ID.`)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .requiredOption(`--documentId `, `Document ID.`)
+ .option(`--limit `, `Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .action(actionRunner(databaseListDocumentLogs))
+
+database
+ .command(`listIndexes`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .action(actionRunner(databaseListIndexes))
+
+database
+ .command(`createIndex`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Index Key.`)
+ .requiredOption(`--type `, `Index type.`)
+ .requiredOption(`--attributes `, `Array of attributes to index.`)
+ .option(`--orders `, `Array of index orders.`)
+ .action(actionRunner(databaseCreateIndex))
+
+database
+ .command(`getIndex`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Index Key.`)
+ .action(actionRunner(databaseGetIndex))
+
+database
+ .command(`deleteIndex`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).`)
+ .requiredOption(`--key `, `Index Key.`)
+ .action(actionRunner(databaseDeleteIndex))
+
+database
+ .command(`listCollectionLogs`)
+ .description(`Get the collection activity logs list by its unique ID.`)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .option(`--limit `, `Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .action(actionRunner(databaseListCollectionLogs))
+
+database
+ .command(`getUsage`)
+ .description(``)
+ .option(`--range `, `Date range.`)
+ .action(actionRunner(databaseGetUsage))
+
+database
+ .command(`getCollectionUsage`)
+ .description(``)
+ .requiredOption(`--collectionId `, `Collection ID.`)
+ .option(`--range `, `Date range.`)
+ .action(actionRunner(databaseGetCollectionUsage))
+
+
+module.exports = {
+ database,
+ databaseListCollections,
+ databaseCreateCollection,
+ databaseGetCollection,
+ databaseUpdateCollection,
+ databaseDeleteCollection,
+ databaseListAttributes,
+ databaseCreateBooleanAttribute,
+ databaseCreateEmailAttribute,
+ databaseCreateEnumAttribute,
+ databaseCreateFloatAttribute,
+ databaseCreateIntegerAttribute,
+ databaseCreateIpAttribute,
+ databaseCreateStringAttribute,
+ databaseCreateUrlAttribute,
+ databaseGetAttribute,
+ databaseDeleteAttribute,
+ databaseListDocuments,
+ databaseCreateDocument,
+ databaseGetDocument,
+ databaseUpdateDocument,
+ databaseDeleteDocument,
+ databaseListDocumentLogs,
+ databaseListIndexes,
+ databaseCreateIndex,
+ databaseGetIndex,
+ databaseDeleteIndex,
+ databaseListCollectionLogs,
+ databaseGetUsage,
+ databaseGetCollectionUsage
+};
\ No newline at end of file
diff --git a/lib/commands/deploy.js b/lib/commands/deploy.js
new file mode 100644
index 0000000..f843ea3
--- /dev/null
+++ b/lib/commands/deploy.js
@@ -0,0 +1,477 @@
+const inquirer = require("inquirer");
+const { Command } = require("commander");
+const { localConfig } = require("../config");
+const { questionsDeployFunctions, questionsGetEntrypoint, questionsDeployCollections } = require("../questions");
+const { actionRunner, success, log, error, commandDescriptions } = require("../parser");
+const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment } = require('./functions');
+const {
+ databaseCreateBooleanAttribute,
+ databaseGetCollection,
+ databaseCreateCollection,
+ databaseCreateStringAttribute,
+ databaseCreateIntegerAttribute,
+ databaseCreateFloatAttribute,
+ databaseCreateEmailAttribute,
+ databaseCreateIndex,
+ databaseCreateUrlAttribute,
+ databaseCreateIpAttribute,
+ databaseCreateEnumAttribute,
+ databaseDeleteAttribute,
+ databaseListAttributes,
+ databaseListIndexes,
+ databaseDeleteIndex
+} = require("./database");
+
+const POOL_DEBOUNCE = 2000; // in milliseconds
+const POOL_MAX_DEBOUNCES = 30;
+
+const awaitPools = {
+ wipeAttributes: async (collectionId, iteration = 1) => {
+ if (iteration > POOL_MAX_DEBOUNCES) {
+ return false;
+ }
+
+ // TODO: Pagination?
+ const { attributes: remoteAttributes } = await databaseListAttributes({
+ collectionId,
+ limit: 100,
+ parseOutput: false
+ });
+
+ if (remoteAttributes.length <= 0) {
+ return true;
+ }
+
+ await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
+ return await awaitPools.wipeAttributes(collectionId, iteration + 1);
+ },
+ wipeIndexes: async (collectionId, iteration = 1) => {
+ if (iteration > POOL_MAX_DEBOUNCES) {
+ return false;
+ }
+
+ // TODO: Pagination?
+ const { indexes: remoteIndexes } = await databaseListIndexes({
+ collectionId,
+ limit: 100,
+ parseOutput: false
+ });
+
+ if (remoteIndexes.length <= 0) {
+ return true;
+ }
+
+ await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
+ return await awaitPools.wipeIndexes(collectionId, iteration + 1);
+ },
+ expectAttributes: async (collectionId, attributeKeys, iteration = 1) => {
+ if (iteration > POOL_MAX_DEBOUNCES) {
+ return false;
+ }
+
+ // TODO: Pagination?
+ const { attributes: remoteAttributes } = await databaseListAttributes({
+ collectionId,
+ limit: 100,
+ parseOutput: false
+ });
+
+ const readyAttributeKeys = remoteAttributes.filter((attribute) => {
+ if (attributeKeys.includes(attribute.key)) {
+ if (['stuck', 'failed'].includes(attribute.status)) {
+ throw new Error(`Attribute '${attribute.key}' failed!`);
+ }
+
+ return attribute.status === 'available';
+ }
+
+ return false;
+ }).map(attribute => attribute.key);
+
+ if (readyAttributeKeys.length >= attributeKeys.length) {
+ return true;
+ }
+
+ await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
+ return await awaitPools.expectAttributes(collectionId, attributeKeys, iteration + 1);
+ },
+ expectIndexes: async (collectionId, indexKeys, iteration = 1) => {
+ if (iteration > POOL_MAX_DEBOUNCES) {
+ return false;
+ }
+
+ // TODO: Pagination?
+ const { indexes: remoteIndexes } = await databaseListIndexes({
+ collectionId,
+ limit: 100,
+ parseOutput: false
+ });
+
+ const readyIndexKeys = remoteIndexes.filter((index) => {
+ if (indexKeys.includes(index.key)) {
+ if (['stuck', 'failed'].includes(index.status)) {
+ throw new Error(`Index '${index.key}' failed!`);
+ }
+
+ return index.status === 'available';
+ }
+
+ return false;
+ }).map(index => index.key);
+
+ if (readyIndexKeys.length >= indexKeys.length) {
+ return true;
+ }
+
+ await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
+ return await awaitPools.expectIndexes(collectionId, indexKeys, iteration + 1);
+ },
+}
+
+const deploy = new Command("deploy")
+ .description(commandDescriptions['deploy'])
+ .option("--all", "Flag to deploy collections and functions")
+ .action(actionRunner(async ({ all }, command) => {
+ if (all == undefined) {
+ command.help()
+ }
+
+ try {
+ await deployFunction();
+ } catch (e) {
+ error(e.message);
+ }
+ await deployCollection()
+ }));
+
+const deployFunction = async () => {
+ let response = {};
+
+ let answers = await inquirer.prompt(questionsDeployFunctions)
+ let functions = answers.functions
+
+ for (let func of functions) {
+ log(`Deploying function ${func.name} ( ${func['$id']} )`)
+
+ try {
+ response = await functionsGet({
+ functionId: func['$id'],
+ parseOutput: false,
+ });
+
+ if(response.runtime !== func.runtime) {
+ throw new Error(`Runtime missmatch! (local=${func.runtime},remote=${response.runtime}) Please delete remote function or update your appwrite.json`);
+ }
+
+ response = await functionsUpdate({
+ functionId: func['$id'],
+ name: func.name,
+ execute: func.execute,
+ vars: func.vars,
+ events: func.events,
+ schedule: func.schedule,
+ timeout: func.timeout,
+ parseOutput: false
+ });
+ } catch (e) {
+ if (e.code == 404) {
+ log(`Function ${func.name} ( ${func['$id']} ) does not exist in the project. Creating ... `);
+ response = await functionsCreate({
+ functionId: func.$id || 'unique()',
+ name: func.name,
+ runtime: func.runtime,
+ execute: func.execute,
+ vars: func.vars,
+ events: func.events,
+ schedule: func.schedule,
+ timeout: func.timeout,
+ parseOutput: false
+ });
+
+ localConfig.updateFunction(func['$id'], {
+ "$id": response['$id'],
+ });
+
+ func["$id"] = response['$id'];
+ log(`Function ${func.name} created.`);
+ } else {
+ throw e;
+ }
+ }
+
+ // Create tag
+ if (!func.entrypoint) {
+ answers = await inquirer.prompt(questionsGetEntrypoint)
+ func.entrypoint = answers.entrypoint;
+ localConfig.updateFunction(func['$id'], func);
+ }
+
+ try {
+ response = await functionsCreateDeployment({
+ functionId: func['$id'],
+ entrypoint: func.entrypoint,
+ code: func.path,
+ activate: true,
+ parseOutput: false
+ })
+
+ success(`Deployed ${func.name} ( ${func['$id']} )`);
+
+ } catch (e) {
+ switch (e.code) {
+ case 'ENOENT':
+ error(`Function ${func.name} ( ${func['$id']} ) not found in the current directory. Skipping ...`);
+ break;
+ default:
+ throw e;
+ }
+ }
+ }
+}
+
+const createAttribute = async (collectionId, attribute) => {
+ switch (attribute.type) {
+ case 'string':
+ switch (attribute.format) {
+ case 'email':
+ return await databaseCreateEmailAttribute({
+ collectionId,
+ key: attribute.key,
+ required: attribute.required,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ case 'url':
+ return await databaseCreateUrlAttribute({
+ collectionId,
+ key: attribute.key,
+ required: attribute.required,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ case 'ip':
+ return await databaseCreateIpAttribute({
+ collectionId,
+ key: attribute.key,
+ required: attribute.required,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ case 'enum':
+ return await databaseCreateEnumAttribute({
+ collectionId,
+ key: attribute.key,
+ elements: attribute.elements,
+ required: attribute.required,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ default:
+ return await databaseCreateStringAttribute({
+ collectionId,
+ key: attribute.key,
+ size: attribute.size,
+ required: attribute.required,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+
+ }
+ case 'integer':
+ return await databaseCreateIntegerAttribute({
+ collectionId,
+ key: attribute.key,
+ required: attribute.required,
+ min: attribute.min,
+ max: attribute.max,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ case 'double':
+ return databaseCreateFloatAttribute({
+ collectionId,
+ key: attribute.key,
+ required: attribute.required,
+ min: attribute.min,
+ max: attribute.max,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ case 'boolean':
+ return databaseCreateBooleanAttribute({
+ collectionId,
+ key: attribute.key,
+ required: attribute.required,
+ xdefault: attribute.default,
+ array: attribute.array,
+ parseOutput: false
+ })
+ }
+}
+
+const deployCollection = async () => {
+ let response = {};
+ let answers = await inquirer.prompt(questionsDeployCollections[0])
+ let collections = answers.collections
+
+ for (let collection of collections) {
+ log(`Deploying collection ${collection.name} ( ${collection['$id']} )`)
+ try {
+ response = await databaseGetCollection({
+ collectionId: collection['$id'],
+ parseOutput: false,
+ })
+ log(`Collection ${collection.name} ( ${collection['$id']} ) already exists.`);
+
+ answers = await inquirer.prompt(questionsDeployCollections[1])
+ if (answers.override !== "YES") {
+ log(`Received "${answers.override}". Skipping ${collection.name} ( ${collection['$id']} )`);
+ continue;
+ }
+
+ log(`Updating attributes ... `);
+
+ // TODO: Pagination?
+ const { indexes: remoteIndexes } = await databaseListIndexes({
+ collectionId: collection['$id'],
+ limit: 100,
+ parseOutput: false
+ });
+
+ await Promise.all(remoteIndexes.map(async index => {
+ await databaseDeleteIndex({
+ collectionId: collection['$id'],
+ key: index.key,
+ parseOutput: false
+ });
+ }));
+
+ const deleteIndexesPoolStatus = await awaitPools.wipeIndexes(collection['$id']);
+ if (!deleteIndexesPoolStatus) {
+ throw new Error("Index deletion did not finish for too long.");
+ }
+
+ // TODO: Pagination?
+ const { attributes: remoteAttributes } = await databaseListAttributes({
+ collectionId: collection['$id'],
+ limit: 100,
+ parseOutput: false
+ });
+
+ await Promise.all(remoteAttributes.map(async attribute => {
+ await databaseDeleteAttribute({
+ collectionId: collection['$id'],
+ key: attribute.key,
+ parseOutput: false
+ });
+ }));
+
+ const deleteAttributesPoolStatus = await awaitPools.wipeAttributes(collection['$id']);
+ if (!deleteAttributesPoolStatus) {
+ throw new Error("Attribute deletion did not finish for too long.");
+ }
+
+ await Promise.all(collection.attributes.map(async attribute => {
+ await createAttribute(collection['$id'], attribute);
+ }));
+
+ const attributeKeys = collection.attributes.map(attribute => attribute.key);
+ const createPoolStatus = await awaitPools.expectAttributes(collection['$id'], attributeKeys);
+ if (!createPoolStatus) {
+ throw new Error("Attribute creation did not finish for too long.");
+ }
+
+ success(`Created ${collection.attributes.length} attributes`);
+
+ log(`Creating indexes ...`)
+ await Promise.all(collection.indexes.map(async index => {
+ await databaseCreateIndex({
+ collectionId: collection['$id'],
+ key: index.key,
+ type: index.type,
+ attributes: index.attributes,
+ orders: index.orders,
+ parseOutput: false
+ });
+ }));
+
+ const indexKeys = collection.indexes.map(attribute => attribute.key);
+ const indexPoolStatus = await awaitPools.expectIndexes(collection['$id'], indexKeys);
+ if (!indexPoolStatus) {
+ throw new Error("Index creation did not finish for too long.");
+ }
+
+ success(`Created ${collection.indexes.length} indexes`);
+ } catch (e) {
+ if (e.code == 404) {
+ log(`Collection ${collection.name} does not exist in the project. Creating ... `);
+ response = await databaseCreateCollection({
+ collectionId: collection['$id'],
+ name: collection.name,
+ permission: collection.permission,
+ read: collection['$read'],
+ write: collection['$write'],
+ parseOutput: false
+ })
+
+ log(`Creating attributes ... `);
+ await Promise.all(collection.attributes.map(async attribute => {
+ await createAttribute(collection['$id'], attribute);
+ }));
+
+ const attributeKeys = collection.attributes.map(attribute => attribute.key);
+ const attributePoolStatus = await awaitPools.expectAttributes(collection['$id'], attributeKeys);
+ if (!attributePoolStatus) {
+ throw new Error("Attribute creation did not finish for too long.");
+ }
+
+ success(`Created ${collection.attributes.length} attributes`);
+
+ log(`Creating indexes ...`);
+ await Promise.all(collection.indexes.map(async index => {
+ await databaseCreateIndex({
+ collectionId: collection['$id'],
+ key: index.key,
+ type: index.type,
+ attributes: index.attributes,
+ orders: index.orders,
+ parseOutput: false
+ });
+ }));
+
+ const indexKeys = collection.indexes.map(attribute => attribute.key);
+ const indexPoolStatus = await awaitPools.expectIndexes(collection['$id'], indexKeys);
+ if (!indexPoolStatus) {
+ throw new Error("Index creation did not finish for too long.");
+ }
+
+ success(`Created ${collection.indexes.length} indexes`);
+
+ success(`Deployed ${collection.name} ( ${collection['$id']} )`);
+ } else {
+ throw e;
+ }
+ }
+ }
+}
+
+deploy
+ .command("function")
+ .description("Deploy functions in the current directory.")
+ .action(actionRunner(deployFunction));
+
+deploy
+ .command("collection")
+ .description("Deploy collections in the current project.")
+ .action(actionRunner(deployCollection));
+
+module.exports = {
+ deploy
+}
\ No newline at end of file
diff --git a/lib/commands/functions.js b/lib/commands/functions.js
new file mode 100644
index 0000000..0d5bb19
--- /dev/null
+++ b/lib/commands/functions.js
@@ -0,0 +1,689 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const functions = new Command("functions").description(commandDescriptions['functions'])
+
+const functionsList = async ({ search, limit, offset, cursor, cursorDirection, orderType, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} search */
+ /* @param {number} limit */
+ /* @param {number} offset */
+ /* @param {string} cursor */
+ /* @param {string} cursorDirection */
+ /* @param {string} orderType */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof search !== 'undefined') {
+ payload['search'] = search;
+ }
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ if (typeof cursor !== 'undefined') {
+ payload['cursor'] = cursor;
+ }
+ if (typeof cursorDirection !== 'undefined') {
+ payload['cursorDirection'] = cursorDirection;
+ }
+ if (typeof orderType !== 'undefined') {
+ payload['orderType'] = orderType;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsCreate = async ({ functionId, name, execute, runtime, vars, events, schedule, timeout, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} name */
+ /* @param {string[]} execute */
+ /* @param {string} runtime */
+ /* @param {object} vars */
+ /* @param {string[]} events */
+ /* @param {string} schedule */
+ /* @param {number} timeout */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof functionId !== 'undefined') {
+ payload['functionId'] = functionId;
+ }
+
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof execute !== 'undefined') {
+ payload['execute'] = execute;
+ }
+
+ if (typeof runtime !== 'undefined') {
+ payload['runtime'] = runtime;
+ }
+
+ if (typeof vars !== 'undefined') {
+ payload['vars'] = vars;
+ }
+
+ if (typeof events !== 'undefined') {
+ payload['events'] = events;
+ }
+
+ if (typeof schedule !== 'undefined') {
+ payload['schedule'] = schedule;
+ }
+
+ if (typeof timeout !== 'undefined') {
+ payload['timeout'] = timeout;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsListRuntimes = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/runtimes';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsGet = async ({ functionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}'.replace('{functionId}', functionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsUpdate = async ({ functionId, name, execute, vars, events, schedule, timeout, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} name */
+ /* @param {string[]} execute */
+ /* @param {object} vars */
+ /* @param {string[]} events */
+ /* @param {string} schedule */
+ /* @param {number} timeout */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}'.replace('{functionId}', functionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof execute !== 'undefined') {
+ payload['execute'] = execute;
+ }
+
+ if (typeof vars !== 'undefined') {
+ payload['vars'] = vars;
+ }
+
+ if (typeof events !== 'undefined') {
+ payload['events'] = events;
+ }
+
+ if (typeof schedule !== 'undefined') {
+ payload['schedule'] = schedule;
+ }
+
+ if (typeof timeout !== 'undefined') {
+ payload['timeout'] = timeout;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsDelete = async ({ functionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}'.replace('{functionId}', functionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsListDeployments = async ({ functionId, search, limit, offset, cursor, cursorDirection, orderType, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} search */
+ /* @param {number} limit */
+ /* @param {number} offset */
+ /* @param {string} cursor */
+ /* @param {string} cursorDirection */
+ /* @param {string} orderType */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/deployments'.replace('{functionId}', functionId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof search !== 'undefined') {
+ payload['search'] = search;
+ }
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ if (typeof cursor !== 'undefined') {
+ payload['cursor'] = cursor;
+ }
+ if (typeof cursorDirection !== 'undefined') {
+ payload['cursorDirection'] = cursorDirection;
+ }
+ if (typeof orderType !== 'undefined') {
+ payload['orderType'] = orderType;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsCreateDeployment = async ({ functionId, entrypoint, code, activate, parseOutput = true, sdk = undefined, onProgress = () => {}}) => {
+ /* @param {string} functionId */
+ /* @param {string} entrypoint */
+ /* @param {File} code */
+ /* @param {boolean} activate */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/deployments'.replace('{functionId}', functionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof entrypoint !== 'undefined') {
+ payload['entrypoint'] = entrypoint;
+ }
+
+ let folderPath = fs.realpathSync(code);
+ if (!fs.lstatSync(folderPath).isDirectory())
+ throw new Error('The path is not a directory.');
+ childProcess.execSync(`tar --cd '${folderPath}' -zcvf code.tar.gz .`, { stdio: 'pipe' });
+ let archivePath = fs.realpathSync('code.tar.gz')
+ if (typeof archivePath !== 'undefined') {
+ payload['code'] = archivePath;
+ }
+
+ if (typeof activate !== 'undefined') {
+ payload['activate'] = activate.toString();
+ }
+
+ let response = undefined;
+ const { size: size } = await promisify(fs.stat)(code);
+
+ if (size <= libClient.CHUNK_SIZE) {
+ payload['code'] = fs.createReadStream(payload['code']);
+
+ response = await client.call('post', path, {
+ 'content-type': 'multipart/form-data',
+ }, payload);
+ } else {
+ const streamFilePath = payload['code'];
+ let id = undefined;
+
+ const totalCounters = Math.ceil(size / libClient.CHUNK_SIZE);
+
+ for (let counter = 0; counter < totalCounters; counter++) {
+ const start = (counter * libClient.CHUNK_SIZE);
+ const end = Math.min((((counter * libClient.CHUNK_SIZE) + libClient.CHUNK_SIZE) - 1), size);
+ const headers = {
+ 'content-type': 'multipart/form-data',
+ 'content-range': 'bytes ' + start + '-' + end + '/' + size
+ };
+
+ if (id) {
+ headers['x-appwrite-id'] = id;
+ }
+
+ const stream = fs.createReadStream(streamFilePath, {
+ start,
+ end
+ });
+ payload['code'] = stream;
+
+ response = await client.call('post', path, headers, payload);
+
+ if (!id) {
+ id = response['$id'];
+ }
+
+ if (onProgress !== null) {
+ onProgress(Math.min((counter+1) * libClient.CHUNK_SIZE, size) / size * 100);
+ }
+ }
+ }
+
+ fs.unlinkSync(archivePath);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsGetDeployment = async ({ functionId, deploymentId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} deploymentId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}', functionId).replace('{deploymentId}', deploymentId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsUpdateDeployment = async ({ functionId, deploymentId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} deploymentId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}', functionId).replace('{deploymentId}', deploymentId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsDeleteDeployment = async ({ functionId, deploymentId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} deploymentId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}', functionId).replace('{deploymentId}', deploymentId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsRetryBuild = async ({ functionId, deploymentId, buildId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} deploymentId */
+ /* @param {string} buildId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/deployments/{deploymentId}/builds/{buildId}'.replace('{functionId}', functionId).replace('{deploymentId}', deploymentId).replace('{buildId}', buildId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsListExecutions = async ({ functionId, limit, offset, search, cursor, cursorDirection, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {number} limit */
+ /* @param {number} offset */
+ /* @param {string} search */
+ /* @param {string} cursor */
+ /* @param {string} cursorDirection */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/executions'.replace('{functionId}', functionId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ if (typeof search !== 'undefined') {
+ payload['search'] = search;
+ }
+ if (typeof cursor !== 'undefined') {
+ payload['cursor'] = cursor;
+ }
+ if (typeof cursorDirection !== 'undefined') {
+ payload['cursorDirection'] = cursorDirection;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsCreateExecution = async ({ functionId, data, async, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} data */
+ /* @param {boolean} async */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/executions'.replace('{functionId}', functionId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof data !== 'undefined') {
+ payload['data'] = data;
+ }
+
+ if (typeof async !== 'undefined') {
+ payload['async'] = async;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsGetExecution = async ({ functionId, executionId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} executionId */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/executions/{executionId}'.replace('{functionId}', functionId).replace('{executionId}', executionId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const functionsGetUsage = async ({ functionId, range, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} functionId */
+ /* @param {string} range */
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/functions/{functionId}/usage'.replace('{functionId}', functionId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof range !== 'undefined') {
+ payload['range'] = range;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+
+functions
+ .command(`list`)
+ .description(`Get a list of all the project's functions. You can use the query params to filter your results.`)
+ .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`)
+ .option(`--limit `, `Maximum number of functions to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .option(`--cursor `, `ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
+ .option(`--cursorDirection `, `Direction of the cursor.`)
+ .option(`--orderType `, `Order result by ASC or DESC order.`)
+ .action(actionRunner(functionsList))
+
+functions
+ .command(`create`)
+ .description(`Create a new function. You can pass a list of [permissions](/docs/permissions) to allow different project users or team with access to execute the function using the client API.`)
+ .requiredOption(`--functionId `, `Function ID. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
+ .requiredOption(`--name `, `Function name. Max length: 128 chars.`)
+ .requiredOption(`--execute `, `An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .requiredOption(`--runtime `, `Execution runtime.`)
+ .option(`--vars `, `Key-value JSON object that will be passed to the function as environment variables.`)
+ .option(`--events `, `Events list.`)
+ .option(`--schedule `, `Schedule CRON syntax.`)
+ .option(`--timeout `, `Function maximum execution time in seconds.`, parseInteger)
+ .action(actionRunner(functionsCreate))
+
+functions
+ .command(`listRuntimes`)
+ .description(`Get a list of all runtimes that are currently active in your project.`)
+ .action(actionRunner(functionsListRuntimes))
+
+functions
+ .command(`get`)
+ .description(`Get a function by its unique ID.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .action(actionRunner(functionsGet))
+
+functions
+ .command(`update`)
+ .description(`Update function by its unique ID.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--name `, `Function name. Max length: 128 chars.`)
+ .requiredOption(`--execute `, `An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
+ .option(`--vars `, `Key-value JSON object that will be passed to the function as environment variables.`)
+ .option(`--events `, `Events list.`)
+ .option(`--schedule `, `Schedule CRON syntax.`)
+ .option(`--timeout `, `Maximum execution time in seconds.`, parseInteger)
+ .action(actionRunner(functionsUpdate))
+
+functions
+ .command(`delete`)
+ .description(`Delete a function by its unique ID.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .action(actionRunner(functionsDelete))
+
+functions
+ .command(`listDeployments`)
+ .description(`Get a list of all the project's code deployments. You can use the query params to filter your results.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`)
+ .option(`--limit `, `Maximum number of deployments to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .option(`--cursor `, `ID of the deployment used as the starting point for the query, excluding the deployment itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
+ .option(`--cursorDirection `, `Direction of the cursor.`)
+ .option(`--orderType `, `Order result by ASC or DESC order.`)
+ .action(actionRunner(functionsListDeployments))
+
+functions
+ .command(`createDeployment`)
+ .description(`Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID. This endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](/docs/functions). Use the "command" param to set the entry point used to execute your code.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--entrypoint `, `Entrypoint File.`)
+ .requiredOption(`--code `, `Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.`)
+ .requiredOption(`--activate `, `Automatically activate the deployment when it is finished building.`, parseBool)
+ .action(actionRunner(functionsCreateDeployment))
+
+functions
+ .command(`getDeployment`)
+ .description(`Get a code deployment by its unique ID.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--deploymentId `, `Deployment ID.`)
+ .action(actionRunner(functionsGetDeployment))
+
+functions
+ .command(`updateDeployment`)
+ .description(`Update the function code deployment ID using the unique function ID. Use this endpoint to switch the code deployment that should be executed by the execution endpoint.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--deploymentId `, `Deployment ID.`)
+ .action(actionRunner(functionsUpdateDeployment))
+
+functions
+ .command(`deleteDeployment`)
+ .description(`Delete a code deployment by its unique ID.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--deploymentId `, `Deployment ID.`)
+ .action(actionRunner(functionsDeleteDeployment))
+
+functions
+ .command(`retryBuild`)
+ .description(``)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--deploymentId `, `Deployment ID.`)
+ .requiredOption(`--buildId `, `Build unique ID.`)
+ .action(actionRunner(functionsRetryBuild))
+
+functions
+ .command(`listExecutions`)
+ .description(`Get a list of all the current user function execution logs. You can use the query params to filter your results. On admin mode, this endpoint will return a list of all of the project's executions. [Learn more about different API modes](/docs/admin).`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .option(`--limit `, `Maximum number of executions to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`)
+ .option(`--cursor `, `ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
+ .option(`--cursorDirection `, `Direction of the cursor.`)
+ .action(actionRunner(functionsListExecutions))
+
+functions
+ .command(`createExecution`)
+ .description(`Trigger a function execution. The returned object will return you the current execution status. You can ping the 'Get Execution' endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .option(`--data `, `String of custom data to send to function.`)
+ .option(`--async `, `Execute code asynchronously. Default value is true.`, parseBool)
+ .action(actionRunner(functionsCreateExecution))
+
+functions
+ .command(`getExecution`)
+ .description(`Get a function execution log by its unique ID.`)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .requiredOption(`--executionId `, `Execution ID.`)
+ .action(actionRunner(functionsGetExecution))
+
+functions
+ .command(`getUsage`)
+ .description(``)
+ .requiredOption(`--functionId `, `Function ID.`)
+ .option(`--range `, `Date range.`)
+ .action(actionRunner(functionsGetUsage))
+
+
+module.exports = {
+ functions,
+ functionsList,
+ functionsCreate,
+ functionsListRuntimes,
+ functionsGet,
+ functionsUpdate,
+ functionsDelete,
+ functionsListDeployments,
+ functionsCreateDeployment,
+ functionsGetDeployment,
+ functionsUpdateDeployment,
+ functionsDeleteDeployment,
+ functionsRetryBuild,
+ functionsListExecutions,
+ functionsCreateExecution,
+ functionsGetExecution,
+ functionsGetUsage
+};
\ No newline at end of file
diff --git a/lib/commands/generic.js b/lib/commands/generic.js
new file mode 100644
index 0000000..5470e14
--- /dev/null
+++ b/lib/commands/generic.js
@@ -0,0 +1,106 @@
+const inquirer = require("inquirer");
+const { Command } = require("commander");
+const { sdkForConsole } = require("../sdks");
+const { globalConfig, localConfig } = require("../config");
+const { actionRunner, success, parseBool, commandDescriptions, log, parse } = require("../parser");
+const { questionsLogin } = require("../questions");
+const { accountCreateSession, accountDeleteSession } = require("./account");
+
+const login = new Command("login")
+ .description(commandDescriptions['login'])
+ .action(actionRunner(async () => {
+ const answers = await inquirer.prompt(questionsLogin)
+
+ let client = await sdkForConsole(false);
+
+ await accountCreateSession({
+ email: answers.email,
+ password: answers.password,
+ parseOutput: false,
+ sdk: client
+ })
+
+ success()
+ }));
+
+const logout = new Command("logout")
+ .description(commandDescriptions['logout'])
+ .action(actionRunner(async () => {
+ let client = await sdkForConsole();
+
+ await accountDeleteSession({
+ sessionId: 'current',
+ parseOutput: false,
+ sdk: client
+ })
+
+ globalConfig.setCookie("");
+ success()
+ }));
+
+const client = new Command("client")
+ .description(commandDescriptions['client'])
+ .option("--selfSigned ", "Configure the CLI to use a self-signed certificate ( true or false )", parseBool)
+ .option("--endpoint ", "Set your Apwrite server endpoint")
+ .option("--projectId ", "Set your Apwrite project ID")
+ .option("--key ", "Set your Apwrite server's API key")
+ .option("--debug", "Print CLI debug information")
+ .option("--reset", "Reset the CLI configuration")
+ .action(actionRunner(async ({ selfSigned, endpoint, projectId, key, debug, reset }, command) => {
+ if (selfSigned == undefined && endpoint == undefined && projectId == undefined && key == undefined && debug == undefined && reset == undefined) {
+ command.help()
+ }
+
+ if (debug) {
+ let config = {
+ endpoint: globalConfig.getEndpoint(),
+ key: globalConfig.getKey(),
+ cookie: globalConfig.getCookie(),
+ selfSigned: globalConfig.getSelfSigned(),
+ project: localConfig.getProject()
+ }
+ parse(config)
+ }
+
+ if (endpoint !== undefined) {
+ try {
+ let url = new URL(endpoint);
+ if (url.protocol === "http:" || url.protocol === "https:") {
+ globalConfig.setEndpoint(endpoint);
+ } else {
+ throw new Error();
+ }
+ } catch (_) {
+ throw new Error("Invalid endpoint");
+ }
+ }
+
+ if (key !== undefined) {
+ globalConfig.setKey(key)
+ }
+
+ if (projectId !== undefined) {
+ localConfig.setProject(projectId, '');
+ }
+
+ if (selfSigned == true || selfSigned == false) {
+ globalConfig.setSelfSigned(selfSigned);
+ }
+
+ if (reset !== undefined) {
+ globalConfig.setEndpoint("");
+ globalConfig.setKey("");
+ globalConfig.setCookie("");
+ globalConfig.setSelfSigned("");
+ localConfig.setProject("", "");
+ }
+
+ success()
+ }));
+
+
+module.exports = {
+ login,
+ logout,
+ client
+};
diff --git a/lib/commands/health.js b/lib/commands/health.js
new file mode 100644
index 0000000..5f940e1
--- /dev/null
+++ b/lib/commands/health.js
@@ -0,0 +1,269 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const health = new Command("health").description(commandDescriptions['health'])
+
+const healthGet = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetAntivirus = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/anti-virus';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetCache = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/cache';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetDB = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/db';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetQueueCertificates = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/queue/certificates';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetQueueFunctions = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/queue/functions';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetQueueLogs = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/queue/logs';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetQueueUsage = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/queue/usage';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetQueueWebhooks = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/queue/webhooks';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetStorageLocal = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/storage/local';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const healthGetTime = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/health/time';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+
+health
+ .command(`get`)
+ .description(`Check the Appwrite HTTP server is up and responsive.`)
+ .action(actionRunner(healthGet))
+
+health
+ .command(`getAntivirus`)
+ .description(`Check the Appwrite Antivirus server is up and connection is successful.`)
+ .action(actionRunner(healthGetAntivirus))
+
+health
+ .command(`getCache`)
+ .description(`Check the Appwrite in-memory cache server is up and connection is successful.`)
+ .action(actionRunner(healthGetCache))
+
+health
+ .command(`getDB`)
+ .description(`Check the Appwrite database server is up and connection is successful.`)
+ .action(actionRunner(healthGetDB))
+
+health
+ .command(`getQueueCertificates`)
+ .description(`Get the number of certificates that are waiting to be issued against [Letsencrypt](https://letsencrypt.org/) in the Appwrite internal queue server.`)
+ .action(actionRunner(healthGetQueueCertificates))
+
+health
+ .command(`getQueueFunctions`)
+ .description(``)
+ .action(actionRunner(healthGetQueueFunctions))
+
+health
+ .command(`getQueueLogs`)
+ .description(`Get the number of logs that are waiting to be processed in the Appwrite internal queue server.`)
+ .action(actionRunner(healthGetQueueLogs))
+
+health
+ .command(`getQueueUsage`)
+ .description(`Get the number of usage stats that are waiting to be processed in the Appwrite internal queue server.`)
+ .action(actionRunner(healthGetQueueUsage))
+
+health
+ .command(`getQueueWebhooks`)
+ .description(`Get the number of webhooks that are waiting to be processed in the Appwrite internal queue server.`)
+ .action(actionRunner(healthGetQueueWebhooks))
+
+health
+ .command(`getStorageLocal`)
+ .description(`Check the Appwrite local storage device is up and connection is successful.`)
+ .action(actionRunner(healthGetStorageLocal))
+
+health
+ .command(`getTime`)
+ .description(`Check the Appwrite server time is synced with Google remote NTP server. We use this technology to smoothly handle leap seconds with no disruptive events. The [Network Time Protocol](https://en.wikipedia.org/wiki/Network_Time_Protocol) (NTP) is used by hundreds of millions of computers and devices to synchronize their clocks over the Internet. If your computer sets its own clock, it likely uses NTP.`)
+ .action(actionRunner(healthGetTime))
+
+
+module.exports = {
+ health,
+ healthGet,
+ healthGetAntivirus,
+ healthGetCache,
+ healthGetDB,
+ healthGetQueueCertificates,
+ healthGetQueueFunctions,
+ healthGetQueueLogs,
+ healthGetQueueUsage,
+ healthGetQueueWebhooks,
+ healthGetStorageLocal,
+ healthGetTime
+};
\ No newline at end of file
diff --git a/lib/commands/init.js b/lib/commands/init.js
new file mode 100644
index 0000000..0d86fb2
--- /dev/null
+++ b/lib/commands/init.js
@@ -0,0 +1,148 @@
+const fs = require("fs");
+const path = require("path");
+const childProcess = require('child_process');
+const { Command } = require("commander");
+const inquirer = require("inquirer");
+const { teamsCreate } = require("./teams");
+const { projectsCreate } = require("./projects");
+const { functionsCreate } = require("./functions");
+const { databaseListCollections } = require("./database");
+const { sdkForConsole } = require("../sdks");
+const { localConfig } = require("../config");
+const { questionsInitProject, questionsInitFunction } = require("../questions");
+const { success, log, actionRunner, commandDescriptions } = require("../parser");
+
+const init = new Command("init")
+ .description(commandDescriptions['init'])
+ .option("--all", "Flag to initialize projects and collection")
+ .action(actionRunner(async ({ all }, command) => {
+ if (all == undefined) {
+ command.help()
+ }
+
+ await initProject();
+ await initCollection()
+ }));
+
+const initProject = async () => {
+ let response = {}
+ let answers = await inquirer.prompt(questionsInitProject)
+ if (!answers.project) process.exit(1)
+
+ let sdk = await sdkForConsole();
+ if (answers.start == "new") {
+ response = await teamsCreate({
+ teamId: 'unique()',
+ name: answers.project,
+ sdk,
+ parseOutput: false
+ })
+
+ let teamId = response['$id'];
+ response = await projectsCreate({
+ projectId: 'unique()',
+ name: answers.project,
+ teamId,
+ parseOutput: false
+ })
+
+ localConfig.setProject(response['$id'], response.name);
+ } else {
+ localConfig.setProject(answers.project.id, answers.project.name);
+ }
+ success();
+}
+
+const initFunction = async () => {
+ let answers = await inquirer.prompt(questionsInitFunction)
+
+ if (fs.existsSync(path.join(process.cwd(), 'functions', answers.name))) {
+ throw new Error(`( ${answers.name} ) already exists in the current directory. Please choose another name.`);
+ }
+
+ if(!answers.runtime.entrypoint) {
+ log(`Entrypoint for this runtime not found. You will be asked to configure entrypoint when you first deploy the function.`);
+ }
+
+ let response = await functionsCreate({
+ functionId: 'unique()',
+ name: answers.name,
+ runtime: answers.runtime.id,
+ parseOutput: false
+ })
+
+ let command = `
+ mkdir -m 777 -p 'functions/${answers.name}' && \
+ cd 'functions/${answers.name}' && \
+ git init && \
+ git remote add -f origin https://github.com/appwrite/functions-starter && \
+ git config core.sparseCheckout true && \
+ echo '${answers.runtime.id}' >> .git/info/sparse-checkout && \
+ git pull origin main && \
+ rm -rf .git && \
+ mv ${answers.runtime.id}/* . && \
+ rm -rf ${answers.runtime.id}`;
+
+ // Execute the child process but do not print any std output
+ childProcess.execSync(command, { stdio: 'pipe' });
+
+ const readmePath = path.join(process.cwd(), 'functions', answers.name, 'README.md');
+ const readmeFile = fs.readFileSync(readmePath).toString();
+ const newReadmeFile = readmeFile.split('\n');
+ newReadmeFile[0] = `# ${answers.name}`;
+ newReadmeFile.splice(1, 2);
+ fs.writeFileSync(readmePath, newReadmeFile.join('\n'));
+
+ let data = {
+ $id: response['$id'],
+ name: response.name,
+ runtime: response.runtime,
+ path: `functions/${answers.name}`,
+ entrypoint: answers.runtime.entrypoint || '',
+ execute: response.execute,
+ vars: response.vars,
+ events: response.events,
+ schedule: response.schedule,
+ timeout: response.timeout,
+ };
+
+ localConfig.addFunction(data);
+ success();
+}
+
+const initCollection = async () => {
+ // TODO: Pagination?
+ let response = await databaseListCollections({
+ limit: 100,
+ parseOutput: false
+ })
+
+ let collections = response.collections;
+ log(`Found ${collections.length} collections`);
+
+ collections.forEach(async collection => {
+ log(`Fetching ${collection.name} ...`);
+ localConfig.addCollection(collection);
+ });
+
+ success();
+}
+
+init
+ .command("project")
+ .description("Initialise your Appwrite project")
+ .action(actionRunner(initProject));
+
+init
+ .command("function")
+ .description("Initialise your Appwrite cloud function")
+ .action(actionRunner(initFunction))
+
+init
+ .command("collection")
+ .description("Initialise your Appwrite collections")
+ .action(actionRunner(initCollection))
+
+module.exports = {
+ init,
+};
diff --git a/lib/commands/locale.js b/lib/commands/locale.js
new file mode 100644
index 0000000..1c4c325
--- /dev/null
+++ b/lib/commands/locale.js
@@ -0,0 +1,177 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const locale = new Command("locale").description(commandDescriptions['locale'])
+
+const localeGet = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const localeGetContinents = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale/continents';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const localeGetCountries = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale/countries';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const localeGetCountriesEU = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale/countries/eu';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const localeGetCountriesPhones = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale/countries/phones';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const localeGetCurrencies = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale/currencies';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const localeGetLanguages = async ({ parseOutput = true, sdk = undefined}) => {
+
+ let client = !sdk ? await sdkForProject() : sdk;
+ let path = '/locale/languages';
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+
+locale
+ .command(`get`)
+ .description(`Get the current user location based on IP. Returns an object with user country code, country name, continent name, continent code, ip address and suggested currency. You can use the locale header to get the data in a supported language. ([IP Geolocation by DB-IP](https://db-ip.com))`)
+ .action(actionRunner(localeGet))
+
+locale
+ .command(`getContinents`)
+ .description(`List of all continents. You can use the locale header to get the data in a supported language.`)
+ .action(actionRunner(localeGetContinents))
+
+locale
+ .command(`getCountries`)
+ .description(`List of all countries. You can use the locale header to get the data in a supported language.`)
+ .action(actionRunner(localeGetCountries))
+
+locale
+ .command(`getCountriesEU`)
+ .description(`List of all countries that are currently members of the EU. You can use the locale header to get the data in a supported language.`)
+ .action(actionRunner(localeGetCountriesEU))
+
+locale
+ .command(`getCountriesPhones`)
+ .description(`List of all countries phone codes. You can use the locale header to get the data in a supported language.`)
+ .action(actionRunner(localeGetCountriesPhones))
+
+locale
+ .command(`getCurrencies`)
+ .description(`List of all currencies, including currency symbol, name, plural, and decimal digits for all major and minor currencies. You can use the locale header to get the data in a supported language.`)
+ .action(actionRunner(localeGetCurrencies))
+
+locale
+ .command(`getLanguages`)
+ .description(`List of all languages classified by ISO 639-1 including 2-letter code, name in English, and name in the respective language.`)
+ .action(actionRunner(localeGetLanguages))
+
+
+module.exports = {
+ locale,
+ localeGet,
+ localeGetContinents,
+ localeGetCountries,
+ localeGetCountriesEU,
+ localeGetCountriesPhones,
+ localeGetCurrencies,
+ localeGetLanguages
+};
\ No newline at end of file
diff --git a/lib/commands/projects.js b/lib/commands/projects.js
new file mode 100644
index 0000000..c5754f8
--- /dev/null
+++ b/lib/commands/projects.js
@@ -0,0 +1,1191 @@
+const fs = require('fs');
+const { promisify } = require('util');
+const libClient = require('../client.js');
+const childProcess = require('child_process');
+const { Command } = require('commander');
+const { sdkForProject, sdkForConsole } = require('../sdks')
+const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
+const { localConfig, globalConfig } = require("../config");
+
+const projects = new Command("projects").description(commandDescriptions['projects'])
+
+const projectsList = async ({ search, limit, offset, cursor, cursorDirection, orderType, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} search */
+ /* @param {number} limit */
+ /* @param {number} offset */
+ /* @param {string} cursor */
+ /* @param {string} cursorDirection */
+ /* @param {string} orderType */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects';
+ let payload = {};
+
+ /** Query Params */
+ if (typeof search !== 'undefined') {
+ payload['search'] = search;
+ }
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+ if (typeof offset !== 'undefined') {
+ payload['offset'] = offset;
+ }
+ if (typeof cursor !== 'undefined') {
+ payload['cursor'] = cursor;
+ }
+ if (typeof cursorDirection !== 'undefined') {
+ payload['cursorDirection'] = cursorDirection;
+ }
+ if (typeof orderType !== 'undefined') {
+ payload['orderType'] = orderType;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsCreate = async ({ projectId, name, teamId, description, logo, url, legalName, legalCountry, legalState, legalCity, legalAddress, legalTaxId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} name */
+ /* @param {string} teamId */
+ /* @param {string} description */
+ /* @param {string} logo */
+ /* @param {string} url */
+ /* @param {string} legalName */
+ /* @param {string} legalCountry */
+ /* @param {string} legalState */
+ /* @param {string} legalCity */
+ /* @param {string} legalAddress */
+ /* @param {string} legalTaxId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects';
+ let payload = {};
+
+ /** Body Params */
+ if (typeof projectId !== 'undefined') {
+ payload['projectId'] = projectId;
+ }
+
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof teamId !== 'undefined') {
+ payload['teamId'] = teamId;
+ }
+
+ if (typeof description !== 'undefined') {
+ payload['description'] = description;
+ }
+
+ if (typeof logo !== 'undefined') {
+ payload['logo'] = logo;
+ }
+
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ if (typeof legalName !== 'undefined') {
+ payload['legalName'] = legalName;
+ }
+
+ if (typeof legalCountry !== 'undefined') {
+ payload['legalCountry'] = legalCountry;
+ }
+
+ if (typeof legalState !== 'undefined') {
+ payload['legalState'] = legalState;
+ }
+
+ if (typeof legalCity !== 'undefined') {
+ payload['legalCity'] = legalCity;
+ }
+
+ if (typeof legalAddress !== 'undefined') {
+ payload['legalAddress'] = legalAddress;
+ }
+
+ if (typeof legalTaxId !== 'undefined') {
+ payload['legalTaxId'] = legalTaxId;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsGet = async ({ projectId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}'.replace('{projectId}', projectId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdate = async ({ projectId, name, description, logo, url, legalName, legalCountry, legalState, legalCity, legalAddress, legalTaxId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} name */
+ /* @param {string} description */
+ /* @param {string} logo */
+ /* @param {string} url */
+ /* @param {string} legalName */
+ /* @param {string} legalCountry */
+ /* @param {string} legalState */
+ /* @param {string} legalCity */
+ /* @param {string} legalAddress */
+ /* @param {string} legalTaxId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof description !== 'undefined') {
+ payload['description'] = description;
+ }
+
+ if (typeof logo !== 'undefined') {
+ payload['logo'] = logo;
+ }
+
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ if (typeof legalName !== 'undefined') {
+ payload['legalName'] = legalName;
+ }
+
+ if (typeof legalCountry !== 'undefined') {
+ payload['legalCountry'] = legalCountry;
+ }
+
+ if (typeof legalState !== 'undefined') {
+ payload['legalState'] = legalState;
+ }
+
+ if (typeof legalCity !== 'undefined') {
+ payload['legalCity'] = legalCity;
+ }
+
+ if (typeof legalAddress !== 'undefined') {
+ payload['legalAddress'] = legalAddress;
+ }
+
+ if (typeof legalTaxId !== 'undefined') {
+ payload['legalTaxId'] = legalTaxId;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsDelete = async ({ projectId, password, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} password */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof password !== 'undefined') {
+ payload['password'] = password;
+ }
+
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateAuthLimit = async ({ projectId, limit, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {number} limit */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/auth/limit'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof limit !== 'undefined') {
+ payload['limit'] = limit;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateAuthStatus = async ({ projectId, method, status, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} method */
+ /* @param {boolean} status */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/auth/{method}'.replace('{projectId}', projectId).replace('{method}', method);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof status !== 'undefined') {
+ payload['status'] = status;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsListDomains = async ({ projectId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/domains'.replace('{projectId}', projectId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsCreateDomain = async ({ projectId, domain, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} domain */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/domains'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof domain !== 'undefined') {
+ payload['domain'] = domain;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsGetDomain = async ({ projectId, domainId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} domainId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/domains/{domainId}'.replace('{projectId}', projectId).replace('{domainId}', domainId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsDeleteDomain = async ({ projectId, domainId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} domainId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/domains/{domainId}'.replace('{projectId}', projectId).replace('{domainId}', domainId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateDomainVerification = async ({ projectId, domainId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} domainId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/domains/{domainId}/verification'.replace('{projectId}', projectId).replace('{domainId}', domainId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsListKeys = async ({ projectId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/keys'.replace('{projectId}', projectId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsCreateKey = async ({ projectId, name, scopes, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} name */
+ /* @param {string[]} scopes */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/keys'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof scopes !== 'undefined') {
+ payload['scopes'] = scopes;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsGetKey = async ({ projectId, keyId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} keyId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/keys/{keyId}'.replace('{projectId}', projectId).replace('{keyId}', keyId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateKey = async ({ projectId, keyId, name, scopes, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} keyId */
+ /* @param {string} name */
+ /* @param {string[]} scopes */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/keys/{keyId}'.replace('{projectId}', projectId).replace('{keyId}', keyId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof scopes !== 'undefined') {
+ payload['scopes'] = scopes;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsDeleteKey = async ({ projectId, keyId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} keyId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/keys/{keyId}'.replace('{projectId}', projectId).replace('{keyId}', keyId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateOAuth2 = async ({ projectId, provider, appId, secret, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} provider */
+ /* @param {string} appId */
+ /* @param {string} secret */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/oauth2'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof provider !== 'undefined') {
+ payload['provider'] = provider;
+ }
+
+ if (typeof appId !== 'undefined') {
+ payload['appId'] = appId;
+ }
+
+ if (typeof secret !== 'undefined') {
+ payload['secret'] = secret;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsListPlatforms = async ({ projectId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/platforms'.replace('{projectId}', projectId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsCreatePlatform = async ({ projectId, type, name, key, store, hostname, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} type */
+ /* @param {string} name */
+ /* @param {string} key */
+ /* @param {string} store */
+ /* @param {string} hostname */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/platforms'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof type !== 'undefined') {
+ payload['type'] = type;
+ }
+
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof store !== 'undefined') {
+ payload['store'] = store;
+ }
+
+ if (typeof hostname !== 'undefined') {
+ payload['hostname'] = hostname;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsGetPlatform = async ({ projectId, platformId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} platformId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/platforms/{platformId}'.replace('{projectId}', projectId).replace('{platformId}', platformId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdatePlatform = async ({ projectId, platformId, name, key, store, hostname, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} platformId */
+ /* @param {string} name */
+ /* @param {string} key */
+ /* @param {string} store */
+ /* @param {string} hostname */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/platforms/{platformId}'.replace('{projectId}', projectId).replace('{platformId}', platformId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof key !== 'undefined') {
+ payload['key'] = key;
+ }
+
+ if (typeof store !== 'undefined') {
+ payload['store'] = store;
+ }
+
+ if (typeof hostname !== 'undefined') {
+ payload['hostname'] = hostname;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsDeletePlatform = async ({ projectId, platformId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} platformId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/platforms/{platformId}'.replace('{projectId}', projectId).replace('{platformId}', platformId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateServiceStatus = async ({ projectId, service, status, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} service */
+ /* @param {boolean} status */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/service'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof service !== 'undefined') {
+ payload['service'] = service;
+ }
+
+ if (typeof status !== 'undefined') {
+ payload['status'] = status;
+ }
+
+ let response = undefined;
+ response = await client.call('patch', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsGetUsage = async ({ projectId, range, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} range */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/usage'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Query Params */
+ if (typeof range !== 'undefined') {
+ payload['range'] = range;
+ }
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsListWebhooks = async ({ projectId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/webhooks'.replace('{projectId}', projectId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsCreateWebhook = async ({ projectId, name, events, url, security, httpUser, httpPass, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} name */
+ /* @param {string[]} events */
+ /* @param {string} url */
+ /* @param {boolean} security */
+ /* @param {string} httpUser */
+ /* @param {string} httpPass */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/webhooks'.replace('{projectId}', projectId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof events !== 'undefined') {
+ payload['events'] = events;
+ }
+
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ if (typeof security !== 'undefined') {
+ payload['security'] = security;
+ }
+
+ if (typeof httpUser !== 'undefined') {
+ payload['httpUser'] = httpUser;
+ }
+
+ if (typeof httpPass !== 'undefined') {
+ payload['httpPass'] = httpPass;
+ }
+
+ let response = undefined;
+ response = await client.call('post', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsGetWebhook = async ({ projectId, webhookId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} webhookId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}', projectId).replace('{webhookId}', webhookId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('get', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsUpdateWebhook = async ({ projectId, webhookId, name, events, url, security, httpUser, httpPass, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} webhookId */
+ /* @param {string} name */
+ /* @param {string[]} events */
+ /* @param {string} url */
+ /* @param {boolean} security */
+ /* @param {string} httpUser */
+ /* @param {string} httpPass */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}', projectId).replace('{webhookId}', webhookId);
+ let payload = {};
+
+ /** Body Params */
+ if (typeof name !== 'undefined') {
+ payload['name'] = name;
+ }
+
+ if (typeof events !== 'undefined') {
+ payload['events'] = events;
+ }
+
+ if (typeof url !== 'undefined') {
+ payload['url'] = url;
+ }
+
+ if (typeof security !== 'undefined') {
+ payload['security'] = security;
+ }
+
+ if (typeof httpUser !== 'undefined') {
+ payload['httpUser'] = httpUser;
+ }
+
+ if (typeof httpPass !== 'undefined') {
+ payload['httpPass'] = httpPass;
+ }
+
+ let response = undefined;
+ response = await client.call('put', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+const projectsDeleteWebhook = async ({ projectId, webhookId, parseOutput = true, sdk = undefined}) => {
+ /* @param {string} projectId */
+ /* @param {string} webhookId */
+
+ let client = !sdk ? await sdkForConsole() : sdk;
+ let path = '/projects/{projectId}/webhooks/{webhookId}'.replace('{projectId}', projectId).replace('{webhookId}', webhookId);
+ let payload = {};
+ let response = undefined;
+ response = await client.call('delete', path, {
+ 'content-type': 'application/json',
+ }, payload);
+
+ if (parseOutput) {
+ parse(response)
+ success()
+ }
+ return response;
+}
+
+
+projects
+ .command(`list`)
+ .description(``)
+ .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`)
+ .option(`--limit `, `Results limit value. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
+ .option(`--offset `, `Results offset. The default value is 0. Use this param to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
+ .option(`--cursor `, `ID of the project used as the starting point for the query, excluding the project itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
+ .option(`--cursorDirection `, `Direction of the cursor.`)
+ .option(`--orderType `, `Order result by ASC or DESC order.`)
+ .action(actionRunner(projectsList))
+
+projects
+ .command(`create`)
+ .description(``)
+ .requiredOption(`--projectId `, `Unique Id. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
+ .requiredOption(`--name `, `Project name. Max length: 128 chars.`)
+ .requiredOption(`--teamId `, `Team unique ID.`)
+ .option(`--description `, `Project description. Max length: 256 chars.`)
+ .option(`--logo `, `Project logo.`)
+ .option(`--url `, `Project URL.`)
+ .option(`--legalName `, `Project legal Name. Max length: 256 chars.`)
+ .option(`--legalCountry `, `Project legal Country. Max length: 256 chars.`)
+ .option(`--legalState `, `Project legal State. Max length: 256 chars.`)
+ .option(`--legalCity