appwrite-cli 0.14.0 → 0.17.0

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.
@@ -1,7 +1,10 @@
1
1
  const fs = require('fs');
2
+ const pathLib = require('path');
3
+ const tar = require("tar");
4
+ const ignore = require("ignore");
2
5
  const { promisify } = require('util');
3
6
  const libClient = require('../client.js');
4
- const childProcess = require('child_process');
7
+ const { getAllFiles } = require('../utils.js');
5
8
  const { Command } = require('commander');
6
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
7
10
  const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
@@ -269,7 +272,7 @@ const storageListFiles = async ({ bucketId, search, limit, offset, cursor, curso
269
272
  const storageCreateFile = async ({ bucketId, fileId, file, read, write, parseOutput = true, sdk = undefined, onProgress = () => {}}) => {
270
273
  /* @param {string} bucketId */
271
274
  /* @param {string} fileId */
272
- /* @param {File} file */
275
+ /* @param {string} file */
273
276
  /* @param {string[]} read */
274
277
  /* @param {string[]} write */
275
278
 
@@ -303,40 +306,57 @@ const storageCreateFile = async ({ bucketId, fileId, file, read, write, parseOut
303
306
 
304
307
  response = await client.call('post', path, {
305
308
  'content-type': 'multipart/form-data',
306
- }, payload);
309
+ }, payload)
307
310
  } else {
308
311
  const streamFilePath = payload['file'];
309
312
  let id = undefined;
310
313
 
314
+ let counter = 0;
311
315
  const totalCounters = Math.ceil(size / libClient.CHUNK_SIZE);
312
316
 
313
- for (let counter = 0; counter < totalCounters; counter++) {
314
- const start = (counter * libClient.CHUNK_SIZE);
315
- const end = Math.min((((counter * libClient.CHUNK_SIZE) + libClient.CHUNK_SIZE) - 1), size);
316
- const headers = {
317
- 'content-type': 'multipart/form-data',
318
- 'content-range': 'bytes ' + start + '-' + end + '/' + size
319
- };
320
-
321
- if (id) {
322
- headers['x-appwrite-id'] = id;
323
- }
324
-
325
- const stream = fs.createReadStream(streamFilePath, {
326
- start,
327
- end
328
- });
329
- payload['file'] = stream;
317
+ const headers = {
318
+ 'content-type': 'multipart/form-data',
319
+ };
320
+
321
+ if(fileId != 'unique()') {
322
+ try {
323
+ response = await client.call('get', path + '/' + fileId, headers);
324
+ counter = response.chunksUploaded;
325
+ } catch(e) {
326
+ }
327
+ }
328
+
329
+ for (counter; counter < totalCounters; counter++) {
330
+ const start = (counter * libClient.CHUNK_SIZE);
331
+ const end = Math.min((((counter * libClient.CHUNK_SIZE) + libClient.CHUNK_SIZE) - 1), size);
332
+
333
+ headers['content-range'] = 'bytes ' + start + '-' + end + '/' + size;
334
+
335
+ if (id) {
336
+ headers['x-appwrite-id'] = id;
337
+ }
338
+
339
+ const stream = fs.createReadStream(streamFilePath, {
340
+ start,
341
+ end
342
+ });
343
+ payload['file'] = stream;
330
344
 
331
- response = await client.call('post', path, headers, payload);
345
+ response = await client.call('post', path, headers, payload);
332
346
 
333
- if (!id) {
334
- id = response['$id'];
335
- }
347
+ if (!id) {
348
+ id = response['$id'];
349
+ }
336
350
 
337
- if (onProgress !== null) {
338
- onProgress(Math.min((counter+1) * libClient.CHUNK_SIZE, size) / size * 100);
339
- }
351
+ if (onProgress !== null) {
352
+ onProgress({
353
+ $id: response['$id'],
354
+ progress: Math.min((counter+1) * libClient.CHUNK_SIZE, size) / size * 100,
355
+ sizeUploaded: end+1,
356
+ chunksTotal: response['chunksTotal'],
357
+ chunksUploaded: response['chunksUploaded']
358
+ });
359
+ }
340
360
  }
341
361
  }
342
362
 
@@ -440,7 +460,7 @@ const storageGetFileDownload = async ({ bucketId, fileId, parseOutput = true, sd
440
460
  }
441
461
  }
442
462
 
443
- const storageGetFilePreview = async ({ bucketId, fileId, width, height, gravity, quality, borderWidth, borderColor, borderRadius, opacity, rotation, background, output, parseOutput = true, sdk = undefined}) => {
463
+ const storageGetFilePreview = async ({ bucketId, fileId, width, height, gravity, quality, borderWidth, borderColor, borderRadius, opacity, rotation, background, output, parseOutput = true, sdk = undefined, destination}) => {
444
464
  /* @param {string} bucketId */
445
465
  /* @param {string} fileId */
446
466
  /* @param {number} width */
@@ -493,16 +513,21 @@ const storageGetFilePreview = async ({ bucketId, fileId, width, height, gravity,
493
513
  if (typeof output !== 'undefined') {
494
514
  payload['output'] = output;
495
515
  }
496
- let response = undefined;
497
- response = await client.call('get', path, {
516
+ payload['project'] = localConfig.getProject().projectId
517
+ payload['key'] = globalConfig.getKey();
518
+ const queryParams = new URLSearchParams(payload);
519
+ path = `${globalConfig.getEndpoint()}${path}?${queryParams.toString()}`;
520
+
521
+ const response = await client.call('get', path, {
498
522
  'content-type': 'application/json',
499
- }, payload);
500
-
501
- if (parseOutput) {
502
- parse(response)
523
+ }, payload, 'arraybuffer');
524
+
525
+ fs.writeFileSync(destination, response);
526
+
527
+ if (parseOutput) {
528
+ log(`File stored in ${destination}`)
503
529
  success()
504
530
  }
505
- return response;
506
531
  }
507
532
 
508
533
  const storageGetFileView = async ({ bucketId, fileId, parseOutput = true, sdk = undefined, destination}) => {
@@ -598,7 +623,7 @@ storage
598
623
  .option(`--write <write...>`, `An array of strings with write permissions. By default no user is granted with any write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.`)
599
624
  .option(`--enabled <enabled>`, `Is bucket enabled?`, parseBool)
600
625
  .option(`--maximumFileSize <maximumFileSize>`, `Maximum file size allowed in bytes. Maximum allowed value is 30MB. For self-hosted setups you can change the max limit by changing the '_APP_STORAGE_LIMIT' environment variable. [Learn more about storage environment variables](docs/environment-variables#storage)`, parseInteger)
601
- .option(`--allowedFileExtensions <allowedFileExtensions...>`, `Allowed file extensions`)
626
+ .option(`--allowedFileExtensions <allowedFileExtensions...>`, `Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.`)
602
627
  .option(`--encryption <encryption>`, `Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled`, parseBool)
603
628
  .option(`--antivirus <antivirus>`, `Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled`, parseBool)
604
629
  .action(actionRunner(storageCreateBucket))
@@ -619,7 +644,7 @@ storage
619
644
  .option(`--write <write...>`, `An array of strings with write permissions. By default inherits the existing write permissions. [learn more about permissions](/docs/permissions) and get a full list of available permissions.`)
620
645
  .option(`--enabled <enabled>`, `Is bucket enabled?`, parseBool)
621
646
  .option(`--maximumFileSize <maximumFileSize>`, `Maximum file size allowed in bytes. Maximum allowed value is 30MB. For self hosted version you can change the limit by changing _APP_STORAGE_LIMIT environment variable. [Learn more about storage environment variables](docs/environment-variables#storage)`, parseInteger)
622
- .option(`--allowedFileExtensions <allowedFileExtensions...>`, `Allowed file extensions`)
647
+ .option(`--allowedFileExtensions <allowedFileExtensions...>`, `Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.`)
623
648
  .option(`--encryption <encryption>`, `Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled`, parseBool)
624
649
  .option(`--antivirus <antivirus>`, `Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled`, parseBool)
625
650
  .action(actionRunner(storageUpdateBucket))
@@ -699,6 +724,7 @@ storage
699
724
  .option(`--rotation <rotation>`, `Preview image rotation in degrees. Pass an integer between -360 and 360.`, parseInteger)
700
725
  .option(`--background <background>`, `Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.`)
701
726
  .option(`--output <output>`, `Output format type (jpeg, jpg, png, gif and webp).`)
727
+ .requiredOption(`--destination <path>`, `output file path.`)
702
728
  .action(actionRunner(storageGetFilePreview))
703
729
 
704
730
  storage
@@ -740,4 +766,4 @@ module.exports = {
740
766
  storageGetFileView,
741
767
  storageGetUsage,
742
768
  storageGetBucketUsage
743
- };
769
+ };
@@ -1,7 +1,10 @@
1
1
  const fs = require('fs');
2
+ const pathLib = require('path');
3
+ const tar = require("tar");
4
+ const ignore = require("ignore");
2
5
  const { promisify } = require('util');
3
6
  const libClient = require('../client.js');
4
- const childProcess = require('child_process');
7
+ const { getAllFiles } = require('../utils.js');
5
8
  const { Command } = require('commander');
6
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
7
10
  const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
@@ -147,6 +150,34 @@ const teamsDelete = async ({ teamId, parseOutput = true, sdk = undefined}) => {
147
150
  return response;
148
151
  }
149
152
 
153
+ const teamsListLogs = async ({ teamId, limit, offset, parseOutput = true, sdk = undefined}) => {
154
+ /* @param {string} teamId */
155
+ /* @param {number} limit */
156
+ /* @param {number} offset */
157
+
158
+ let client = !sdk ? await sdkForProject() : sdk;
159
+ let path = '/teams/{teamId}/logs'.replace('{teamId}', teamId);
160
+ let payload = {};
161
+
162
+ /** Query Params */
163
+ if (typeof limit !== 'undefined') {
164
+ payload['limit'] = limit;
165
+ }
166
+ if (typeof offset !== 'undefined') {
167
+ payload['offset'] = offset;
168
+ }
169
+ let response = undefined;
170
+ response = await client.call('get', path, {
171
+ 'content-type': 'application/json',
172
+ }, payload);
173
+
174
+ if (parseOutput) {
175
+ parse(response)
176
+ success()
177
+ }
178
+ return response;
179
+ }
180
+
150
181
  const teamsGetMemberships = async ({ teamId, search, limit, offset, cursor, cursorDirection, orderType, parseOutput = true, sdk = undefined}) => {
151
182
  /* @param {string} teamId */
152
183
  /* @param {string} search */
@@ -343,7 +374,7 @@ teams
343
374
  .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.`)
344
375
  .requiredOption(`--teamId <teamId>`, `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.`)
345
376
  .requiredOption(`--name <name>`, `Team name. Max length: 128 chars.`)
346
- .option(`--roles <roles...>`, `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.`)
377
+ .option(`--roles <roles...>`, `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). Maximum of 100 roles are allowed, each 32 characters long.`)
347
378
  .action(actionRunner(teamsCreate))
348
379
 
349
380
  teams
@@ -365,6 +396,14 @@ teams
365
396
  .requiredOption(`--teamId <teamId>`, `Team ID.`)
366
397
  .action(actionRunner(teamsDelete))
367
398
 
399
+ teams
400
+ .command(`listLogs`)
401
+ .description(`Get the team activity logs list by its unique ID.`)
402
+ .requiredOption(`--teamId <teamId>`, `Team ID.`)
403
+ .option(`--limit <limit>`, `Maximum number of logs to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
404
+ .option(`--offset <offset>`, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
405
+ .action(actionRunner(teamsListLogs))
406
+
368
407
  teams
369
408
  .command(`getMemberships`)
370
409
  .description(`Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint.`)
@@ -382,7 +421,7 @@ teams
382
421
  .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.`)
383
422
  .requiredOption(`--teamId <teamId>`, `Team ID.`)
384
423
  .requiredOption(`--email <email>`, `Email of the new team member.`)
385
- .requiredOption(`--roles <roles...>`, `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.`)
424
+ .requiredOption(`--roles <roles...>`, `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). Maximum of 100 roles are allowed, each 32 characters long.`)
386
425
  .requiredOption(`--url <url>`, `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.`)
387
426
  .option(`--name <name>`, `Name of the new team member. Max length: 128 chars.`)
388
427
  .action(actionRunner(teamsCreateMembership))
@@ -399,7 +438,7 @@ teams
399
438
  .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).`)
400
439
  .requiredOption(`--teamId <teamId>`, `Team ID.`)
401
440
  .requiredOption(`--membershipId <membershipId>`, `Membership ID.`)
402
- .requiredOption(`--roles <roles...>`, `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.`)
441
+ .requiredOption(`--roles <roles...>`, `An array of strings. Use this param to set the user's roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of 100 roles are allowed, each 32 characters long.`)
403
442
  .action(actionRunner(teamsUpdateMembershipRoles))
404
443
 
405
444
  teams
@@ -426,10 +465,11 @@ module.exports = {
426
465
  teamsGet,
427
466
  teamsUpdate,
428
467
  teamsDelete,
468
+ teamsListLogs,
429
469
  teamsGetMemberships,
430
470
  teamsCreateMembership,
431
471
  teamsGetMembership,
432
472
  teamsUpdateMembershipRoles,
433
473
  teamsDeleteMembership,
434
474
  teamsUpdateMembershipStatus
435
- };
475
+ };
@@ -1,7 +1,10 @@
1
1
  const fs = require('fs');
2
+ const pathLib = require('path');
3
+ const tar = require("tar");
4
+ const ignore = require("ignore");
2
5
  const { promisify } = require('util');
3
6
  const libClient = require('../client.js');
4
- const childProcess = require('child_process');
7
+ const { getAllFiles } = require('../utils.js');
5
8
  const { Command } = require('commander');
6
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
7
10
  const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
@@ -207,6 +210,24 @@ const usersGetLogs = async ({ userId, limit, offset, parseOutput = true, sdk = u
207
210
  return response;
208
211
  }
209
212
 
213
+ const usersGetMemberships = async ({ userId, parseOutput = true, sdk = undefined}) => {
214
+ /* @param {string} userId */
215
+
216
+ let client = !sdk ? await sdkForProject() : sdk;
217
+ let path = '/users/{userId}/memberships'.replace('{userId}', userId);
218
+ let payload = {};
219
+ let response = undefined;
220
+ response = await client.call('get', path, {
221
+ 'content-type': 'application/json',
222
+ }, payload);
223
+
224
+ if (parseOutput) {
225
+ parse(response)
226
+ success()
227
+ }
228
+ return response;
229
+ }
230
+
210
231
  const usersUpdateName = async ({ userId, name, parseOutput = true, sdk = undefined}) => {
211
232
  /* @param {string} userId */
212
233
  /* @param {string} name */
@@ -285,7 +306,7 @@ const usersUpdatePrefs = async ({ userId, prefs, parseOutput = true, sdk = undef
285
306
 
286
307
  /** Body Params */
287
308
  if (typeof prefs !== 'undefined') {
288
- payload['prefs'] = prefs;
309
+ payload['prefs'] = JSON.parse(prefs);
289
310
  }
290
311
 
291
312
  let response = undefined;
@@ -441,7 +462,7 @@ users
441
462
 
442
463
  users
443
464
  .command(`delete`)
444
- .description(`Delete a user by its unique ID.`)
465
+ .description(`Delete a user by its unique ID, thereby releasing it's ID. Since ID is released and can be reused, all user-related resources like documents or storage files should be deleted before user deletion. If you want to keep ID reserved, use the [updateStatus](/docs/server/users#usersUpdateStatus) endpoint instead.`)
445
466
  .requiredOption(`--userId <userId>`, `User ID.`)
446
467
  .action(actionRunner(usersDelete))
447
468
 
@@ -460,6 +481,12 @@ users
460
481
  .option(`--offset <offset>`, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
461
482
  .action(actionRunner(usersGetLogs))
462
483
 
484
+ users
485
+ .command(`getMemberships`)
486
+ .description(`Get the user membership list by its unique ID.`)
487
+ .requiredOption(`--userId <userId>`, `User ID.`)
488
+ .action(actionRunner(usersGetMemberships))
489
+
463
490
  users
464
491
  .command(`updateName`)
465
492
  .description(`Update the user name by its unique ID.`)
@@ -508,7 +535,7 @@ users
508
535
 
509
536
  users
510
537
  .command(`updateStatus`)
511
- .description(`Update the user status by its unique ID.`)
538
+ .description(`Update the user status by its unique ID. Use this endpoint as an alternative to deleting a user if you want to keep user's ID reserved.`)
512
539
  .requiredOption(`--userId <userId>`, `User ID.`)
513
540
  .requiredOption(`--status <status>`, `User Status. To activate the user pass 'true' and to block the user pass 'false'.`, parseBool)
514
541
  .action(actionRunner(usersUpdateStatus))
@@ -530,6 +557,7 @@ module.exports = {
530
557
  usersDelete,
531
558
  usersUpdateEmail,
532
559
  usersGetLogs,
560
+ usersGetMemberships,
533
561
  usersUpdateName,
534
562
  usersUpdatePassword,
535
563
  usersGetPrefs,
@@ -539,4 +567,4 @@ module.exports = {
539
567
  usersDeleteSession,
540
568
  usersUpdateStatus,
541
569
  usersUpdateVerification
542
- };
570
+ };
package/lib/config.js CHANGED
@@ -2,6 +2,7 @@ const os = require('os');
2
2
  const fs = require("fs");
3
3
  const _path = require("path");
4
4
  const process = require("process");
5
+ const JSONbig = require("json-bigint")({ storeAsString: false });
5
6
 
6
7
  class Config {
7
8
  constructor(path) {
@@ -11,7 +12,8 @@ class Config {
11
12
 
12
13
  read() {
13
14
  try {
14
- this.data = require(this.path);
15
+ const file = fs.readFileSync(this.path).toString();
16
+ this.data = JSONbig.parse(file);
15
17
  } catch (e) {
16
18
  // console.log(`${this.path} not found. Empty data`);
17
19
  this.data = {};
@@ -23,7 +25,7 @@ class Config {
23
25
  if (!fs.existsSync(dir)){
24
26
  fs.mkdirSync(dir, { recursive: true });
25
27
  }
26
- fs.writeFileSync(this.path, JSON.stringify(this.data, null, 4));
28
+ fs.writeFileSync(this.path, JSONbig.stringify(this.data, null, 4));
27
29
  }
28
30
 
29
31
  get(key) {
@@ -46,7 +48,7 @@ class Config {
46
48
  }
47
49
 
48
50
  has(key) {
49
- return this.data.hasOwnProperty(key);
51
+ return this.data[key] !== undefined;
50
52
  }
51
53
 
52
54
  keys() {
@@ -58,7 +60,7 @@ class Config {
58
60
  }
59
61
 
60
62
  toString() {
61
- return JSON.stringify(this.data, null, 4);
63
+ return JSONbig.stringify(this.data, null, 4);
62
64
  }
63
65
  }
64
66
 
package/lib/questions.js CHANGED
@@ -1,6 +1,39 @@
1
1
  const { localConfig } = require('./config');
2
2
  const { projectsList } = require('./commands/projects');
3
3
  const { functionsListRuntimes } = require('./commands/functions');
4
+ const JSONbig = require("json-bigint")({ storeAsString: false });
5
+
6
+ const getIgnores = (runtime) => {
7
+ const languge = runtime.split('-')[0];
8
+
9
+ switch (languge) {
10
+ case 'cpp':
11
+ return ['build', 'CMakeFiles', 'CMakeCaches.txt'];
12
+ case 'dart':
13
+ return ['.packages', '.dart_tool'];
14
+ case 'deno':
15
+ return [];
16
+ case 'dotnet':
17
+ return ['bin', 'obj', '.nuget'];
18
+ case 'java':
19
+ case 'kotlin':
20
+ return ['build'];
21
+ case 'node':
22
+ return ['node_modules', '.npm'];
23
+ case 'php':
24
+ return ['vendor'];
25
+ case 'python':
26
+ return ['__pypackages__'];
27
+ case 'ruby':
28
+ return ['vendor'];
29
+ case 'rust':
30
+ return ['target', 'debug', '*.rs.bk', '*.pdb'];
31
+ case 'swift':
32
+ return ['.build', '.swiftpm'];
33
+ }
34
+
35
+ return undefined;
36
+ };
4
37
 
5
38
  const getEntrypoint = (runtime) => {
6
39
  const languge = runtime.split('-')[0];
@@ -117,7 +150,7 @@ const questionsInitFunction = [
117
150
  let choices = runtimes.map((runtime, idx) => {
118
151
  return {
119
152
  name: `${runtime.name} (${runtime['$id']})`,
120
- value: { id: runtime['$id'], entrypoint: getEntrypoint(runtime['$id'])}
153
+ value: { id: runtime['$id'], entrypoint: getEntrypoint(runtime['$id']), ignore: getIgnores(runtime['$id'])},
121
154
  }
122
155
  })
123
156
  return choices;
@@ -185,7 +218,7 @@ const questionsDeployCollections = [
185
218
  let choices = collections.map((collection, idx) => {
186
219
  return {
187
220
  name: `${collection.name} (${collection['$id']})`,
188
- value: collection
221
+ value: JSONbig.stringify(collection)
189
222
  }
190
223
  })
191
224
  return choices;
package/lib/sdks.js CHANGED
@@ -7,7 +7,23 @@ const questionGetEndpoint = [
7
7
  type: "input",
8
8
  name: "endpoint",
9
9
  message: "Enter the endpoint of your Appwrite server",
10
- default: "http://localhost/v1"
10
+ default: "http://localhost/v1",
11
+ async validate(value) {
12
+ if (!value) {
13
+ return "Please enter a valid endpoint.";
14
+ }
15
+ let client = new Client().setEndpoint(value);
16
+ try {
17
+ let response = await client.call('get', '/health/version');
18
+ if (response.version) {
19
+ return true;
20
+ } else {
21
+ throw new Error();
22
+ }
23
+ } catch (error) {
24
+ return "Invalid endpoint or your Appwrite server is not running as expected.";
25
+ }
26
+ }
11
27
  }
12
28
  ]
13
29
 
package/lib/utils.js ADDED
@@ -0,0 +1,19 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ function getAllFiles(folder) {
5
+ const files = [];
6
+ for(const pathDir of fs.readdirSync(folder)) {
7
+ const pathAbsolute = path.join(folder, pathDir);
8
+ if (fs.statSync(pathAbsolute).isDirectory()) {
9
+ files.push(...getAllFiles(pathAbsolute));
10
+ } else {
11
+ files.push(pathAbsolute);
12
+ }
13
+ }
14
+ return files;
15
+ }
16
+
17
+ module.exports = {
18
+ getAllFiles
19
+ };
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": "0.14.0",
5
+ "version": "0.17.0",
6
6
  "license": "BSD-3-Clause",
7
7
  "main": "index.js",
8
8
  "bin": {
@@ -22,12 +22,15 @@
22
22
  "windows-arm64": "pkg -t node16-win-arm64 -o build/appwrite-cli-win-arm64.exe package.json"
23
23
  },
24
24
  "dependencies": {
25
- "axios": "^0.24.0",
25
+ "axios": "^0.27.2",
26
26
  "chalk": "4.1.2",
27
- "cli-table3": "^0.6.1",
28
- "commander": "^8.3.0",
27
+ "cli-table3": "^0.6.2",
28
+ "commander": "^9.2.0",
29
29
  "form-data": "^4.0.0",
30
- "inquirer": "^8.2.0"
30
+ "json-bigint": "^1.0.0",
31
+ "inquirer": "^8.2.4",
32
+ "tar": "^6.1.11",
33
+ "ignore": "^5.2.0"
31
34
  },
32
35
  "devDependencies": {
33
36
  "pkg": "5.5.1"
@@ -1 +0,0 @@
1
- appwrite account delete
@@ -1 +0,0 @@
1
- appwrite health getQueueUsage