appwrite-cli 6.0.0-rc.2 → 6.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using
29
29
 
30
30
  ```sh
31
31
  $ appwrite -v
32
- 6.0.0-rc.2
32
+ 6.0.0-rc.3
33
33
  ```
34
34
 
35
35
  ### Install using prebuilt binaries
@@ -60,7 +60,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc
60
60
  Once the installation completes, you can verify your install using
61
61
  ```
62
62
  $ appwrite -v
63
- 6.0.0-rc.2
63
+ 6.0.0-rc.3
64
64
  ```
65
65
 
66
66
  ## Getting Started
package/install.ps1 CHANGED
@@ -13,8 +13,8 @@
13
13
  # You can use "View source" of this page to see the full script.
14
14
 
15
15
  # REPO
16
- $GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.2/appwrite-cli-win-x64.exe"
17
- $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.2/appwrite-cli-win-arm64.exe"
16
+ $GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.3/appwrite-cli-win-x64.exe"
17
+ $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.3/appwrite-cli-win-arm64.exe"
18
18
 
19
19
  $APPWRITE_BINARY_NAME = "appwrite.exe"
20
20
 
package/install.sh CHANGED
@@ -97,7 +97,7 @@ printSuccess() {
97
97
  downloadBinary() {
98
98
  echo "[2/4] Downloading executable for $OS ($ARCH) ..."
99
99
 
100
- GITHUB_LATEST_VERSION="6.0.0-rc.2"
100
+ GITHUB_LATEST_VERSION="6.0.0-rc.3"
101
101
  GITHUB_FILE="appwrite-cli-${OS}-${ARCH}"
102
102
  GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE"
103
103
 
package/lib/client.js CHANGED
@@ -16,8 +16,8 @@ class Client {
16
16
  'x-sdk-name': 'Command Line',
17
17
  'x-sdk-platform': 'console',
18
18
  'x-sdk-language': 'cli',
19
- 'x-sdk-version': '6.0.0-rc.2',
20
- 'user-agent' : `AppwriteCLI/6.0.0-rc.2 (${os.type()} ${os.version()}; ${os.arch()})`,
19
+ 'x-sdk-version': '6.0.0-rc.3',
20
+ 'user-agent' : `AppwriteCLI/6.0.0-rc.3 (${os.type()} ${os.version()}; ${os.arch()})`,
21
21
  'X-Appwrite-Response-Format' : '1.5.0',
22
22
  };
23
23
  }
@@ -168,7 +168,7 @@ class Client {
168
168
 
169
169
  body = formData;
170
170
  } else {
171
- body = JSON.stringify(params);
171
+ body = JSONbig.stringify(params);
172
172
  }
173
173
 
174
174
  let response = undefined;
@@ -224,7 +224,7 @@ class Client {
224
224
  const text = await response.text();
225
225
  let json = undefined;
226
226
  try {
227
- json = JSON.parse(text);
227
+ json = JSONbig.parse(text);
228
228
  } catch (error) {
229
229
  return text;
230
230
  }
@@ -11,7 +11,7 @@ const { databasesGet, databasesListCollections, databasesList } = require("./dat
11
11
  const { storageListBuckets } = require("./storage");
12
12
  const { localConfig } = require("../config");
13
13
  const { paginate } = require("../paginate");
14
- const { questionsPullCollection, questionsPullFunctions, questionsPullResources } = require("../questions");
14
+ const { questionsPullCollection, questionsPullFunctions, questionsPullFunctionsCode, questionsPullResources } = require("../questions");
15
15
  const { cliConfig, success, log, warn, actionRunner, commandDescriptions } = require("../parser");
16
16
 
17
17
  const pullResources = async () => {
@@ -56,7 +56,7 @@ const pullSettings = async () => {
56
56
  }
57
57
  }
58
58
 
59
- const pullFunctions = async () => {
59
+ const pullFunctions = async ({ code }) => {
60
60
  log("Fetching functions ...");
61
61
  let total = 0;
62
62
 
@@ -74,11 +74,15 @@ const pullFunctions = async () => {
74
74
  ? (await paginate(functionsList, { parseOutput: false }, 100, 'functions')).functions
75
75
  : (await inquirer.prompt(questionsPullFunctions)).functions;
76
76
 
77
+ let allowCodePull = cliConfig.force === true ? true : null;
78
+
77
79
  for (let func of functions) {
78
80
  total++;
79
81
  log(`Pulling function ${chalk.bold(func['name'])} ...`);
80
82
 
81
83
  const localFunction = localConfig.getFunction(func.$id);
84
+
85
+ func['path'] = localFunction['path'];
82
86
  if(!localFunction['path']) {
83
87
  func['path'] = `functions/${func.$id}`;
84
88
  }
@@ -88,28 +92,40 @@ const pullFunctions = async () => {
88
92
  if (!fs.existsSync(func['path'])) {
89
93
  fs.mkdirSync(func['path'], { recursive: true });
90
94
  }
91
-
92
- if(func['deployment']) {
93
- const compressedFileName = `${func['$id']}-${+new Date()}.tar.gz`
94
- await functionsDownloadDeployment({
95
- functionId: func['$id'],
96
- deploymentId: func['deployment'],
97
- destination: compressedFileName,
98
- overrideForCli: true,
99
- parseOutput: false
100
- });
101
-
102
- tar.extract({
103
- sync: true,
104
- cwd: func['path'],
105
- file: compressedFileName,
106
- strict: false,
107
- });
108
-
109
- fs.rmSync(compressedFileName);
110
- }
111
- }
95
+
96
+ if(code === false) {
97
+ warn("Source code download skipped.");
98
+ } else if(!func['deployment']) {
99
+ warn("Source code download skipped because function doesn't have active deployment.");
100
+ } else {
101
+ if(allowCodePull === null) {
102
+ const codeAnswer = await inquirer.prompt(questionsPullFunctionsCode);
103
+ allowCodePull = codeAnswer.override;
104
+ }
105
+
106
+ if(allowCodePull) {
107
+ log("Pulling active deployment's code ...");
108
+
109
+ const compressedFileName = `${func['$id']}-${+new Date()}.tar.gz`
110
+ await functionsDownloadDeployment({
111
+ functionId: func['$id'],
112
+ deploymentId: func['deployment'],
113
+ destination: compressedFileName,
114
+ overrideForCli: true,
115
+ parseOutput: false
116
+ });
112
117
 
118
+ tar.extract({
119
+ sync: true,
120
+ cwd: func['path'],
121
+ file: compressedFileName,
122
+ strict: false,
123
+ });
124
+
125
+ fs.rmSync(compressedFileName);
126
+ }
127
+ }
128
+
113
129
  success(`Successfully pulled ${chalk.bold(total)} functions.`);
114
130
  }
115
131
 
@@ -261,6 +277,7 @@ pull
261
277
  .command("function")
262
278
  .alias("functions")
263
279
  .description("Pulling your Appwrite cloud function")
280
+ .option("--no-code", "Don't pull the function's code")
264
281
  .action(actionRunner(pullFunctions))
265
282
 
266
283
  pull
@@ -67,7 +67,7 @@ const { checkDeployConditions } = require('../utils');
67
67
 
68
68
  const STEP_SIZE = 100; // Resources
69
69
  const POLL_DEBOUNCE = 2000; // Milliseconds
70
- const POLL_MAX_DEBOUNCE = 30; // Times
70
+ const POLL_MAX_DEBOUNCE = 1800; // Times of POLL_DEBOUNCE (1 hour)
71
71
 
72
72
  let pollMaxDebounces = 30;
73
73
 
@@ -354,8 +354,8 @@ const createAttribute = async (databaseId, collectionId, attribute) => {
354
354
  collectionId,
355
355
  key: attribute.key,
356
356
  required: attribute.required,
357
- min: parseInt(attribute.min.toString()),
358
- max: parseInt(attribute.max.toString()),
357
+ min: attribute.min,
358
+ max: attribute.max,
359
359
  xdefault: attribute.default,
360
360
  array: attribute.array,
361
361
  parseOutput: false
@@ -366,8 +366,8 @@ const createAttribute = async (databaseId, collectionId, attribute) => {
366
366
  collectionId,
367
367
  key: attribute.key,
368
368
  required: attribute.required,
369
- min: parseFloat(attribute.min.toString()),
370
- max: parseFloat(attribute.max.toString()),
369
+ min: attribute.min,
370
+ max: attribute.max,
371
371
  xdefault: attribute.default,
372
372
  array: attribute.array,
373
373
  parseOutput: false
@@ -471,8 +471,8 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
471
471
  collectionId,
472
472
  key: attribute.key,
473
473
  required: attribute.required,
474
- min: parseInt(attribute.min.toString()),
475
- max: parseInt(attribute.max.toString()),
474
+ min: attribute.min,
475
+ max: attribute.max,
476
476
  xdefault: attribute.default,
477
477
  array: attribute.array,
478
478
  parseOutput: false
@@ -483,8 +483,8 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
483
483
  collectionId,
484
484
  key: attribute.key,
485
485
  required: attribute.required,
486
- min: parseFloat(attribute.min.toString()),
487
- max: parseFloat(attribute.max.toString()),
486
+ min: attribute.min,
487
+ max: attribute.max,
488
488
  xdefault: attribute.default,
489
489
  array: attribute.array,
490
490
  parseOutput: false
@@ -884,6 +884,7 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
884
884
  logging: func.logging,
885
885
  entrypoint: func.entrypoint,
886
886
  commands: func.commands,
887
+ scopes: func.scopes,
887
888
  providerRepositoryId: func.providerRepositoryId ?? "",
888
889
  installationId: func.installationId ?? '',
889
890
  providerBranch: func.providerBranch ?? '',
@@ -86,12 +86,12 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
86
86
  log("If you wish to change your local settings, update the appwrite.json file and rerun the 'appwrite run' command.");
87
87
  hint("Permissions, events, CRON and timeouts dont apply when running locally.");
88
88
 
89
- await dockerCleanup();
89
+ await dockerCleanup(func.$id);
90
90
 
91
91
  process.on('SIGINT', async () => {
92
92
  log('Cleaning up ...');
93
- await dockerCleanup();
94
- success();
93
+ await dockerCleanup(func.$id);
94
+ success("Local function successfully stopped.");
95
95
  process.exit();
96
96
  });
97
97
 
@@ -135,7 +135,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
135
135
  variables['APPWRITE_FUNCTION_RUNTIME_VERSION'] = func.runtime;
136
136
 
137
137
  try {
138
- await JwtManager.setup(userId);
138
+ await JwtManager.setup(userId, func.scopes ?? []);
139
139
  } catch(err) {
140
140
  warn("Dynamic API key not generated. Header x-appwrite-key will not be set. Reason: " + err.message);
141
141
  }
@@ -149,18 +149,12 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
149
149
  variables['OPEN_RUNTIMES_HEADERS'] = JSON.stringify(headers);
150
150
 
151
151
  await dockerPull(func);
152
- await dockerBuild(func, variables);
153
-
154
- log('Starting function using Docker ...');
155
- hint('Function automatically restarts when you edit your code.');
156
-
157
- await dockerStart(func, variables, port);
158
152
 
159
153
  new Tail(logsPath).on("line", function(data) {
160
- process.stdout.write(chalk.blackBright(`${data}\n`));
154
+ process.stdout.write(chalk.white(`${data}\n`));
161
155
  });
162
156
  new Tail(errorsPath).on("line", function(data) {
163
- process.stdout.write(chalk.blackBright(`${data}\n`));
157
+ process.stdout.write(chalk.white(`${data}\n`));
164
158
  });
165
159
 
166
160
  if(!noReload) {
@@ -181,8 +175,14 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
181
175
 
182
176
  const dependencyFile = files.find((filePath) => tool.dependencyFiles.includes(filePath));
183
177
  if(tool.isCompiled || dependencyFile) {
184
- log(`Rebuilding the function ...`);
178
+ log(`Rebuilding the function due to file changes ...`);
185
179
  await dockerBuild(func, variables);
180
+
181
+ if(!Queue.isEmpty()) {
182
+ Queue.unlock();
183
+ return;
184
+ }
185
+
186
186
  await dockerStart(func, variables, port);
187
187
  } else {
188
188
  log('Hot-swapping function.. Files with change are ' + files.join(', '));
@@ -247,6 +247,22 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
247
247
  Queue.unlock();
248
248
  }
249
249
  });
250
+
251
+ Queue.lock();
252
+
253
+ log('Building function using Docker ...');
254
+ await dockerBuild(func, variables);
255
+
256
+ if(!Queue.isEmpty()) {
257
+ Queue.unlock();
258
+ return;
259
+ }
260
+
261
+ log('Starting function using Docker ...');
262
+ hint('Function automatically restarts when you edit your code.');
263
+ await dockerStart(func, variables, port);
264
+
265
+ Queue.unlock();
250
266
  }
251
267
 
252
268
  const run = new Command("run")
package/lib/config.js CHANGED
@@ -4,15 +4,36 @@ const _path = require("path");
4
4
  const process = require("process");
5
5
  const JSONbig = require("json-bigint")({ storeAsString: false });
6
6
 
7
- const KeysFunction = ["path", "$id", "execute", "name", "enabled", "logging", "runtime", "scopes", "events", "schedule", "timeout", "entrypoint", "commands"];
8
- const KeysDatabase = ["$id", "name", "enabled"];
9
- const KeysCollection = ["$id", "$permissions", "databaseId", "name", "enabled", "documentSecurity", "attributes", "indexes"];
10
- const KeysStorage = ["$id", "$permissions", "fileSecurity", "name", "enabled", "maximumFileSize", "allowedFileExtensions", "compression", "encryption", "antivirus"];
11
- const KeyTopics = ["$id", "name", "subscribe"];
12
- const KeyAttributes = ["key", "type", "required", "array", "size", "default"];
13
- const KeyIndexes = ["key", "type", "status", "attributes", "orders"];
14
-
15
- function whitelistKeys(value, keys, nestedKeys = []) {
7
+ const KeysFunction = new Set(["path", "$id", "execute", "name", "enabled", "logging", "runtime", "scopes", "events", "schedule", "timeout", "entrypoint", "commands"]);
8
+ const KeysDatabase = new Set(["$id", "name", "enabled"]);
9
+ const KeysCollection = new Set(["$id", "$permissions", "databaseId", "name", "enabled", "documentSecurity", "attributes", "indexes"]);
10
+ const KeysStorage = new Set(["$id", "$permissions", "fileSecurity", "name", "enabled", "maximumFileSize", "allowedFileExtensions", "compression", "encryption", "antivirus"]);
11
+ const KeyTopics = new Set(["$id", "name", "subscribe"]);
12
+ const KeyAttributes = new Set([
13
+ "key",
14
+ "type",
15
+ "required",
16
+ "array",
17
+ "size",
18
+ "default",
19
+ // integer and float
20
+ "min",
21
+ "max",
22
+ // email, enum, URL, IP, and datetime
23
+ "format",
24
+ // enum
25
+ "elements",
26
+ // relationship
27
+ "relatedCollection",
28
+ "relationType",
29
+ "twoWay",
30
+ "twoWayKey",
31
+ "onDelete",
32
+ "side"
33
+ ]);
34
+ const KeyIndexes = new Set(["key", "type", "status", "attributes", "orders"]);
35
+
36
+ function whitelistKeys(value, keys, nestedKeys = {}) {
16
37
  if(Array.isArray(value)) {
17
38
  const newValue = [];
18
39
 
@@ -25,7 +46,7 @@ function whitelistKeys(value, keys, nestedKeys = []) {
25
46
 
26
47
  const newValue = {};
27
48
  Object.keys(value).forEach((key) => {
28
- if(keys.includes(key)) {
49
+ if(keys.has(key)) {
29
50
  if(nestedKeys[key]) {
30
51
  newValue[key] = whitelistKeys(value[key], nestedKeys[key]);
31
52
  } else {
@@ -4,11 +4,15 @@ const { localConfig } = require("../config");
4
4
  const path = require('path');
5
5
  const fs = require('fs');
6
6
  const { log, success, hint } = require("../parser");
7
- const { openRuntimesVersion, systemTools } = require("./utils");
7
+ const { openRuntimesVersion, systemTools, Queue } = require("./utils");
8
8
 
9
9
  async function dockerStop(id) {
10
10
  const stopProcess = childProcess.spawn('docker', ['rm', '--force', id], {
11
11
  stdio: 'pipe',
12
+ env: {
13
+ ...process.env,
14
+ DOCKER_CLI_HINTS: 'false'
15
+ }
12
16
  });
13
17
 
14
18
  await new Promise((res) => { stopProcess.on('close', res) });
@@ -20,45 +24,20 @@ async function dockerPull(func) {
20
24
  const runtimeName = runtimeChunks.join("-");
21
25
  const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
22
26
 
23
- const checkProcess = childProcess.spawn('docker', ['images', '--format', 'json', imageName], {
24
- stdio: 'pipe',
25
- pwd: path.join(process.cwd(), func.path)
26
- });
27
-
28
- let hasImage = false;
29
-
30
- checkProcess.stdout.on('data', (data) => {
31
- if(data) {
32
- hasImage = false;
33
- }
34
- });
35
-
36
- checkProcess.stderr.on('data', (data) => {
37
- if(data) {
38
- hasImage = false;
39
- }
40
- });
41
-
42
- await new Promise((res) => { checkProcess.on('close', res) });
43
-
44
- if(hasImage) {
45
- return;
46
- }
47
-
48
- log('Pulling Docker image ...');
49
- hint('This may take a few minutes, but we only need to do this once.');
27
+ log('Verifying Docker image ...');
50
28
 
51
29
  const pullProcess = childProcess.spawn('docker', ['pull', imageName], {
52
30
  stdio: 'pipe',
53
- pwd: path.join(process.cwd(), func.path)
31
+ env: {
32
+ ...process.env,
33
+ DOCKER_CLI_HINTS: 'false'
34
+ }
54
35
  });
55
36
 
56
37
  await new Promise((res) => { pullProcess.on('close', res) });
57
38
  }
58
39
 
59
40
  async function dockerBuild(func, variables) {
60
- log('Building function using Docker ...');
61
-
62
41
  const runtimeChunks = func.runtime.split("-");
63
42
  const runtimeVersion = runtimeChunks.pop();
64
43
  const runtimeName = runtimeChunks.join("-");
@@ -74,7 +53,6 @@ async function dockerBuild(func, variables) {
74
53
  params.push('-e', 'APPWRITE_ENV=development');
75
54
  params.push('-e', 'OPEN_RUNTIMES_ENV=development');
76
55
  params.push('-e', 'OPEN_RUNTIMES_SECRET=');
77
- params.push('-l', 'appwrite-env=dev');
78
56
  params.push('-e', `OPEN_RUNTIMES_ENTRYPOINT=${func.entrypoint}`);
79
57
 
80
58
  for(const k of Object.keys(variables)) {
@@ -85,7 +63,11 @@ async function dockerBuild(func, variables) {
85
63
 
86
64
  const buildProcess = childProcess.spawn('docker', params, {
87
65
  stdio: 'pipe',
88
- pwd: functionDir
66
+ pwd: functionDir,
67
+ env: {
68
+ ...process.env,
69
+ DOCKER_CLI_HINTS: 'false'
70
+ }
89
71
  });
90
72
 
91
73
  buildProcess.stdout.on('data', (data) => {
@@ -96,8 +78,25 @@ async function dockerBuild(func, variables) {
96
78
  process.stderr.write(chalk.blackBright(`${data}\n`));
97
79
  });
98
80
 
81
+ const killInterval = setInterval(() => {
82
+ if(!Queue.isEmpty()) {
83
+ log('Cancelling build ...');
84
+ buildProcess.stdout.destroy();
85
+ buildProcess.stdin.destroy();
86
+ buildProcess.stderr.destroy();
87
+ buildProcess.kill("SIGKILL");
88
+ clearInterval(killInterval);
89
+ }
90
+ }, 100);
91
+
99
92
  await new Promise((res) => { buildProcess.on('close', res) });
100
93
 
94
+ clearInterval(interval);
95
+
96
+ if(!Queue.isEmpty()) {
97
+ return;
98
+ }
99
+
101
100
  const copyPath = path.join(process.cwd(), func.path, '.appwrite', 'build.tar.gz');
102
101
  const copyDir = path.dirname(copyPath);
103
102
  if (!fs.existsSync(copyDir)) {
@@ -106,7 +105,11 @@ async function dockerBuild(func, variables) {
106
105
 
107
106
  const copyProcess = childProcess.spawn('docker', ['cp', `${id}:/mnt/code/code.tar.gz`, copyPath], {
108
107
  stdio: 'pipe',
109
- pwd: functionDir
108
+ pwd: functionDir,
109
+ env: {
110
+ ...process.env,
111
+ DOCKER_CLI_HINTS: 'false'
112
+ }
110
113
  });
111
114
 
112
115
  await new Promise((res) => { copyProcess.on('close', res) });
@@ -133,10 +136,8 @@ async function dockerStart(func, variables, port) {
133
136
 
134
137
  const params = [ 'run' ];
135
138
  params.push('--rm');
136
- params.push('-d');
137
139
  params.push('--name', id);
138
140
  params.push('-p', `${port}:3000`);
139
- params.push('-l', 'appwrite-env=dev');
140
141
  params.push('-e', 'APPWRITE_ENV=development');
141
142
  params.push('-e', 'OPEN_RUNTIMES_ENV=development');
142
143
  params.push('-e', 'OPEN_RUNTIMES_SECRET=');
@@ -150,58 +151,38 @@ async function dockerStart(func, variables, port) {
150
151
  params.push('-v', `${functionDir}/.appwrite/build.tar.gz:/mnt/code/code.tar.gz:ro`);
151
152
  params.push(imageName, 'sh', '-c', `helpers/start.sh "${tool.startCommand}"`);
152
153
 
153
- childProcess.spawn('docker', params, {
154
+ const startProcess = childProcess.spawn('docker', params, {
154
155
  stdio: 'pipe',
155
- pwd: functionDir
156
+ pwd: functionDir,
157
+ env: {
158
+ ...process.env,
159
+ DOCKER_CLI_HINTS: 'false'
160
+ }
156
161
  });
157
162
 
158
- success(`Visit http://localhost:${port}/ to execute your function.`);
159
- }
160
-
161
- async function dockerCleanup() {
162
- await dockerStopActive();
163
+ startProcess.stdout.on('data', (data) => {
164
+ process.stdout.write(chalk.blackBright(data));
165
+ });
163
166
 
164
- const functions = localConfig.getFunctions();
165
- for(const func of functions) {
166
- const appwritePath = path.join(process.cwd(), func.path, '.appwrite');
167
- if (fs.existsSync(appwritePath)) {
168
- fs.rmSync(appwritePath, { recursive: true, force: true });
169
- }
167
+ startProcess.stderr.on('data', (data) => {
168
+ process.stdout.write(chalk.blackBright(data));
169
+ });
170
170
 
171
- const tempPath = path.join(process.cwd(), func.path, 'code.tar.gz');
172
- if (fs.existsSync(tempPath)) {
173
- fs.rmSync(tempPath, { force: true });
174
- }
175
- }
171
+ success(`Visit http://localhost:${port}/ to execute your function.`);
176
172
  }
177
173
 
178
- async function dockerStopActive() {
179
- const listProcess = childProcess.spawn('docker', ['ps', '-a', '-q', '--filter', 'label=appwrite-env=dev'], {
180
- stdio: 'pipe',
181
- });
174
+ async function dockerCleanup(functionId) {
175
+ await dockerStop(functionId);
182
176
 
183
- const ids = [];
184
- function handleOutput(data) {
185
- const list = data.toString().split('\n');
186
- for(const id of list) {
187
- if(id && !id.includes(' ')) {
188
- ids.push(id);
189
- }
190
- }
177
+ const func = localConfig.getFunction(functionId);
178
+ const appwritePath = path.join(process.cwd(), func.path, '.appwrite');
179
+ if (fs.existsSync(appwritePath)) {
180
+ fs.rmSync(appwritePath, { recursive: true, force: true });
191
181
  }
192
182
 
193
- listProcess.stdout.on('data', (data) => {
194
- handleOutput(data);
195
- });
196
-
197
- listProcess.stderr.on('data', (data) => {
198
- handleOutput(data);
199
- });
200
-
201
- await new Promise((res) => { listProcess.on('close', res) });
202
-
203
- for(const id of ids) {
204
- await dockerStop(id);
183
+ const tempPath = path.join(process.cwd(), func.path, 'code.tar.gz');
184
+ if (fs.existsSync(tempPath)) {
185
+ fs.rmSync(tempPath, { force: true });
205
186
  }
206
187
  }
207
188
 
@@ -210,6 +191,5 @@ module.exports = {
210
191
  dockerBuild,
211
192
  dockerStart,
212
193
  dockerCleanup,
213
- dockerStopActive,
214
194
  dockerStop,
215
195
  }
@@ -1,6 +1,8 @@
1
1
  const EventEmitter = require('node:events');
2
2
  const { projectsCreateJWT } = require('../commands/projects');
3
3
  const { localConfig } = require("../config");
4
+ const { usersGet, usersCreateJWT } = require("../commands/users");
5
+ const { log } = require("../parser");
4
6
 
5
7
  const openRuntimesVersion = 'v4';
6
8
 
@@ -95,7 +97,7 @@ const JwtManager = {
95
97
  timerWarn: null,
96
98
  timerError: null,
97
99
 
98
- async setup(userId = null) {
100
+ async setup(userId = null, projectScopes = []) {
99
101
  if(this.timerWarn) {
100
102
  clearTimeout(this.timerWarn);
101
103
  }
@@ -128,8 +130,7 @@ const JwtManager = {
128
130
 
129
131
  const functionResponse = await projectsCreateJWT({
130
132
  projectId: localConfig.getProject().projectId,
131
- // TODO: Once we have endpoint for this, use it
132
- scopes: ["sessions.write","users.read","users.write","teams.read","teams.write","databases.read","databases.write","collections.read","collections.write","attributes.read","attributes.write","indexes.read","indexes.write","documents.read","documents.write","files.read","files.write","buckets.read","buckets.write","functions.read","functions.write","execution.read","execution.write","locale.read","avatars.read","health.read","providers.read","providers.write","messages.read","messages.write","topics.read","topics.write","subscribers.read","subscribers.write","targets.read","targets.write","rules.read","rules.write","migrations.read","migrations.write","vcs.read","vcs.write","assistant.read"],
133
+ scopes: projectScopes,
133
134
  duration: 60*60,
134
135
  parseOutput: false
135
136
  });
@@ -155,6 +156,9 @@ const Queue = {
155
156
  this.files = [];
156
157
  this.locked = true;
157
158
  },
159
+ isEmpty() {
160
+ return this.files.length === 0
161
+ },
158
162
  unlock() {
159
163
  this.locked = false;
160
164
  if(this.files.length > 0) {
package/lib/parser.js CHANGED
@@ -131,7 +131,7 @@ const parseError = (err) => {
131
131
  } catch {
132
132
  }
133
133
 
134
- const version = '6.0.0-rc.2';
134
+ const version = '6.0.0-rc.3';
135
135
  const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
136
136
  const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud}`;
137
137
 
package/lib/questions.js CHANGED
@@ -258,6 +258,14 @@ const questionsPullFunctions = [
258
258
  }
259
259
  ];
260
260
 
261
+ const questionsPullFunctionsCode = [
262
+ {
263
+ type: "confirm",
264
+ name: "override",
265
+ message: "Do you want to pull source code of active deployment?"
266
+ },
267
+ ];
268
+
261
269
  const questionsCreateFunction = [
262
270
  {
263
271
  type: "input",
@@ -841,6 +849,7 @@ module.exports = {
841
849
  questionsCreateCollection,
842
850
  questionsCreateMessagingTopic,
843
851
  questionsPullFunctions,
852
+ questionsPullFunctionsCode,
844
853
  questionsLogin,
845
854
  questionsPullResources,
846
855
  questionsLogout,
package/lib/sdks.js CHANGED
@@ -30,7 +30,7 @@ const sdkForProject = async () => {
30
30
  let selfSigned = globalConfig.getSelfSigned()
31
31
 
32
32
  if (!project) {
33
- throw new Error("Project is not set. Please run `appwrite init` to initialize the current directory with an Appwrite project.");
33
+ throw new Error("Project is not set. Please run `appwrite init project` to initialize the current directory with an Appwrite project.");
34
34
  }
35
35
 
36
36
  client
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "appwrite-cli",
3
3
  "homepage": "https://appwrite.io/support",
4
4
  "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",
5
- "version": "6.0.0-rc.2",
5
+ "version": "6.0.0-rc.3",
6
6
  "license": "BSD-3-Clause",
7
7
  "main": "index.js",
8
8
  "bin": {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
3
- "version": "6.0.0-rc.2",
3
+ "version": "6.0.0-rc.3",
4
4
  "description": "The Appwrite CLI is a command-line application that allows you to interact with Appwrite and perform server-side tasks using your terminal.",
5
5
  "homepage": "https://github.com/appwrite/sdk-for-cli",
6
6
  "license": "BSD-3-Clause",
7
7
  "architecture": {
8
8
  "64bit": {
9
- "url": "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.2/appwrite-cli-win-x64.exe",
9
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.3/appwrite-cli-win-x64.exe",
10
10
  "bin": [
11
11
  [
12
12
  "appwrite-cli-win-x64.exe",
@@ -15,7 +15,7 @@
15
15
  ]
16
16
  },
17
17
  "arm64": {
18
- "url": "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.2/appwrite-cli-win-arm64.exe",
18
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.3/appwrite-cli-win-arm64.exe",
19
19
  "bin": [
20
20
  [
21
21
  "appwrite-cli-win-arm64.exe",