appwrite-cli 5.0.5 → 6.0.0-rc.1

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.
Files changed (53) hide show
  1. package/README.md +4 -4
  2. package/docs/examples/functions/create-build.md +1 -1
  3. package/docs/examples/functions/create-execution.md +1 -0
  4. package/docs/examples/functions/create.md +1 -0
  5. package/docs/examples/functions/delete-execution.md +3 -0
  6. package/docs/examples/functions/update-deployment-build.md +3 -0
  7. package/docs/examples/functions/update.md +1 -0
  8. package/docs/examples/projects/create-j-w-t.md +4 -0
  9. package/docs/examples/projects/update-mock-numbers.md +3 -0
  10. package/docs/examples/projects/update-session-alerts.md +3 -0
  11. package/docs/examples/users/create-j-w-t.md +4 -0
  12. package/docs/examples/vcs/get-repository-contents.md +4 -0
  13. package/index.js +34 -7
  14. package/install.ps1 +3 -3
  15. package/install.sh +2 -2
  16. package/lib/client.js +17 -3
  17. package/lib/commands/account.js +306 -152
  18. package/lib/commands/assistant.js +8 -5
  19. package/lib/commands/avatars.js +114 -58
  20. package/lib/commands/console.js +8 -5
  21. package/lib/commands/databases.js +353 -164
  22. package/lib/commands/functions.js +310 -100
  23. package/lib/commands/generic.js +206 -54
  24. package/lib/commands/graphql.js +14 -8
  25. package/lib/commands/health.js +140 -71
  26. package/lib/commands/init.js +250 -155
  27. package/lib/commands/locale.js +50 -26
  28. package/lib/commands/messaging.js +334 -156
  29. package/lib/commands/migrations.js +98 -50
  30. package/lib/commands/project.js +38 -20
  31. package/lib/commands/projects.js +449 -144
  32. package/lib/commands/proxy.js +32 -17
  33. package/lib/commands/pull.js +231 -0
  34. package/lib/commands/push.js +1518 -0
  35. package/lib/commands/run.js +282 -0
  36. package/lib/commands/storage.js +160 -76
  37. package/lib/commands/teams.js +102 -50
  38. package/lib/commands/users.js +324 -134
  39. package/lib/commands/vcs.js +102 -29
  40. package/lib/config.js +190 -18
  41. package/lib/emulation/docker.js +187 -0
  42. package/lib/emulation/utils.js +177 -0
  43. package/lib/id.js +30 -0
  44. package/lib/paginate.js +1 -2
  45. package/lib/parser.js +69 -12
  46. package/lib/questions.js +452 -80
  47. package/lib/sdks.js +1 -1
  48. package/lib/spinner.js +103 -0
  49. package/lib/utils.js +242 -4
  50. package/lib/validations.js +17 -0
  51. package/package.json +6 -2
  52. package/scoop/appwrite.json +3 -3
  53. package/lib/commands/deploy.js +0 -940
package/lib/questions.js CHANGED
@@ -1,15 +1,22 @@
1
- const { localConfig } = require('./config');
1
+ const chalk = require("chalk");
2
+ const Client = require("./client");
3
+ const { localConfig, globalConfig } = require('./config');
2
4
  const { projectsList } = require('./commands/projects');
3
- const { functionsListRuntimes } = require('./commands/functions');
5
+ const { teamsList } = require('./commands/teams');
6
+ const { functionsListRuntimes, functionsList } = require('./commands/functions');
4
7
  const { accountListMfaFactors } = require("./commands/account");
5
8
  const { sdkForConsole } = require("./sdks");
6
-
9
+ const { validateRequired } = require("./validations");
10
+ const { paginate } = require('./paginate');
11
+ const { isPortTaken } = require('./utils');
7
12
  const { databasesList } = require('./commands/databases');
8
13
  const { checkDeployConditions } = require('./utils');
9
14
  const JSONbig = require("json-bigint")({ storeAsString: false });
10
15
 
16
+ const whenOverride = (answers) => answers.override === undefined ? true : answers.override;
17
+
11
18
  const getIgnores = (runtime) => {
12
- const languge = runtime.split('-')[0];
19
+ const languge = runtime.split("-").slice(0, -1).join("-");
13
20
 
14
21
  switch (languge) {
15
22
  case 'cpp':
@@ -29,6 +36,7 @@ const getIgnores = (runtime) => {
29
36
  case 'php':
30
37
  return ['vendor'];
31
38
  case 'python':
39
+ case 'python-ml':
32
40
  return ['__pypackages__'];
33
41
  case 'ruby':
34
42
  return ['vendor'];
@@ -42,7 +50,7 @@ const getIgnores = (runtime) => {
42
50
  };
43
51
 
44
52
  const getEntrypoint = (runtime) => {
45
- const languge = runtime.split('-')[0];
53
+ const languge = runtime.split("-").slice(0, -1).join("-");
46
54
 
47
55
  switch (languge) {
48
56
  case 'dart':
@@ -56,6 +64,7 @@ const getEntrypoint = (runtime) => {
56
64
  case 'php':
57
65
  return 'src/index.php';
58
66
  case 'python':
67
+ case 'python-ml':
59
68
  return 'src/main.py';
60
69
  case 'ruby':
61
70
  return 'lib/main.rb';
@@ -77,7 +86,7 @@ const getEntrypoint = (runtime) => {
77
86
  };
78
87
 
79
88
  const getInstallCommand = (runtime) => {
80
- const languge = runtime.split('-')[0];
89
+ const languge = runtime.split("-").slice(0, -1).join("-");
81
90
 
82
91
  switch (languge) {
83
92
  case 'dart':
@@ -91,6 +100,7 @@ const getInstallCommand = (runtime) => {
91
100
  case 'php':
92
101
  return 'composer install';
93
102
  case 'python':
103
+ case 'python-ml':
94
104
  return 'pip install -r requirements.txt';
95
105
  case 'ruby':
96
106
  return 'bundle install';
@@ -113,7 +123,7 @@ const questionsInitProject = [
113
123
  type: "confirm",
114
124
  name: "override",
115
125
  message:
116
- `An Appwrite project ( ${localConfig.getProject()['projectName']} ) is already associated with the current directory. Would you like to override`,
126
+ `An Appwrite project ( ${localConfig.getProject()['projectId']} ) is already associated with the current directory. Would you like to override`,
117
127
  when() {
118
128
  return Object.keys(localConfig.getProject()).length !== 0;
119
129
  }
@@ -121,61 +131,72 @@ const questionsInitProject = [
121
131
  {
122
132
  type: "list",
123
133
  name: "start",
124
- when(answers) {
125
- if (answers.override == undefined) {
126
- return true
127
- }
128
- return answers.override;
129
- },
134
+ when: whenOverride,
130
135
  message: "How would you like to start?",
131
136
  choices: [
132
137
  {
133
- name: "Create a new Appwrite project",
134
- value: "new",
138
+ name: "Create new project",
139
+ value: "new"
135
140
  },
136
141
  {
137
- name: "Link this directory to an existing Appwrite project",
138
- value: "existing",
139
- },
140
- ],
142
+ name: "Link directory to an existing project",
143
+ value: "existing"
144
+ }
145
+ ]
146
+ },
147
+ {
148
+ type: "search-list",
149
+ name: "organization",
150
+ message: "Choose your organization",
151
+ choices: async () => {
152
+ let client = await sdkForConsole(true);
153
+ const { teams } = await paginate(teamsList, { parseOutput: false, sdk: client }, 100, 'teams');
154
+
155
+ let choices = teams.map((team, idx) => {
156
+ return {
157
+ name: `${team.name} (${team['$id']})`,
158
+ value: team['$id']
159
+ }
160
+ })
161
+
162
+ if (choices.length == 0) {
163
+ throw new Error(`No organizations found. Please create a new organization at ${globalConfig.getEndpoint().replace('/v1', '/console/onboarding')}`)
164
+ }
165
+
166
+ return choices;
167
+ },
168
+ when: whenOverride
141
169
  },
142
170
  {
143
171
  type: "input",
144
172
  name: "project",
145
173
  message: "What would you like to name your project?",
146
174
  default: "My Awesome Project",
147
- when(answers) {
148
- return answers.start == "new";
149
- },
175
+ when: (answer) => answer.start !== 'existing'
150
176
  },
151
177
  {
152
178
  type: "input",
153
179
  name: "id",
154
180
  message: "What ID would you like to have for your project?",
155
181
  default: "unique()",
156
- when(answers) {
157
- return answers.start == "new";
158
- },
182
+ when: (answer) => answer.start !== 'existing'
159
183
  },
160
184
  {
161
- type: "list",
185
+ type: "search-list",
162
186
  name: "project",
163
187
  message: "Choose your Appwrite project.",
164
- when(answers) {
165
- return answers.start == "existing";
166
- },
167
- choices: async () => {
168
- let response = await projectsList({
169
- parseOutput: false
170
- })
171
- let projects = response["projects"]
172
- let choices = projects.map((project, idx) => {
188
+ choices: async (answers) => {
189
+ const queries = [
190
+ JSON.stringify({ method: 'equal', attribute: 'teamId', values: [answers.organization.id] }),
191
+ JSON.stringify({ method: 'orderDesc', attribute: 'Id' })
192
+ ]
193
+
194
+ const { projects } = await paginate(projectsList, { parseOutput: false, queries, }, 100, 'projects');
195
+
196
+ let choices = projects.map((project) => {
173
197
  return {
174
198
  name: `${project.name} (${project['$id']})`,
175
- value: {
176
- name: project.name,
177
- id: project['$id']
178
- }
199
+ value: project['$id']
179
200
  }
180
201
  })
181
202
 
@@ -184,11 +205,50 @@ const questionsInitProject = [
184
205
  }
185
206
 
186
207
  return choices;
208
+ },
209
+ when: (answer) => answer.start === 'existing'
210
+ }
211
+ ];
212
+ const questionsPullResources = [
213
+ {
214
+ type: "list",
215
+ name: "resource",
216
+ message: "Which resources would you like to pull?",
217
+ choices: [
218
+ { name: 'Project', value: 'project' },
219
+ { name: 'Functions', value: 'functions' },
220
+ { name: 'Collections', value: 'collections' },
221
+ { name: 'Buckets', value: 'buckets' },
222
+ { name: 'Teams', value: 'teams' },
223
+ { name: 'Topics', value: 'messages' }
224
+ ]
225
+ }
226
+ ]
227
+
228
+ const questionsPullFunctions = [
229
+ {
230
+ type: "checkbox",
231
+ name: "functions",
232
+ message: "Which functions would you like to pull?",
233
+ validate: (value) => validateRequired('function', value),
234
+ choices: async () => {
235
+ const { functions } = await paginate(functionsList, { parseOutput: false }, 100, 'functions');
236
+
237
+ if (functions.length === 0) {
238
+ throw "We couldn't find any functions in your Appwrite project";
239
+ }
240
+
241
+ return functions.map(func => {
242
+ return {
243
+ name: `${func.name} (${func.$id})`,
244
+ value: func
245
+ }
246
+ });
187
247
  }
188
248
  }
189
249
  ];
190
250
 
191
- const questionsInitFunction = [
251
+ const questionsCreateFunction = [
192
252
  {
193
253
  type: "input",
194
254
  name: "name",
@@ -215,9 +275,10 @@ const questionsInitFunction = [
215
275
  name: `${runtime.name} (${runtime['$id']})`,
216
276
  value: {
217
277
  id: runtime['$id'],
278
+ name: runtime['$id'].split('-')[0],
218
279
  entrypoint: getEntrypoint(runtime['$id']),
219
280
  ignore: getIgnores(runtime['$id']),
220
- commands : getInstallCommand(runtime['$id'])
281
+ commands: getInstallCommand(runtime['$id'])
221
282
  },
222
283
  }
223
284
  })
@@ -226,11 +287,146 @@ const questionsInitFunction = [
226
287
  }
227
288
  ];
228
289
 
229
- const questionsInitCollection = [
290
+ const questionsCreateFunctionSelectTemplate = (templates) => {
291
+ return [
292
+ {
293
+ type: "search-list",
294
+ name: "template",
295
+ message: "What template would you like to use?",
296
+ choices: templates.map((template) => {
297
+ const name = `${template[0].toUpperCase()}${template.split('').slice(1).join('')}`.replace(/[-_]/g, ' ');
298
+
299
+ return { value: template, name }
300
+ })
301
+ }
302
+ ];
303
+ };
304
+
305
+
306
+
307
+ const questionsCreateBucket = [
308
+ {
309
+ type: "input",
310
+ name: "bucket",
311
+ message: "What would you like to name your bucket?",
312
+ default: "My Awesome Bucket"
313
+ },
314
+ {
315
+ type: "input",
316
+ name: "id",
317
+ message: "What ID would you like to have for your bucket?",
318
+ default: "unique()"
319
+ },
320
+ {
321
+ type: "list",
322
+ name: "fileSecurity",
323
+ message: "Enable File-Security configuring permissions for individual file",
324
+ choices: ["No", "Yes"]
325
+ }
326
+ ];
327
+
328
+ const questionsCreateTeam = [
329
+ {
330
+ type: "input",
331
+ name: "bucket",
332
+ message: "What would you like to name your team?",
333
+ default: "My Awesome Team"
334
+ },
335
+ {
336
+ type: "input",
337
+ name: "id",
338
+ message: "What ID would you like to have for your team?",
339
+ default: "unique()"
340
+ }
341
+ ];
342
+
343
+ const questionsCreateCollection = [
344
+ {
345
+ type: "list",
346
+ name: "method",
347
+ message: "What database would you like to use for your collection",
348
+ choices: ["New", "Existing"],
349
+ when: async () => {
350
+ return localConfig.getDatabases().length !== 0;
351
+ }
352
+ },
353
+ {
354
+ type: "search-list",
355
+ name: "database",
356
+ message: "Choose the collection database",
357
+ choices: async () => {
358
+ const databases = localConfig.getDatabases();
359
+
360
+ let choices = databases.map((database, idx) => {
361
+ return {
362
+ name: `${database.name} (${database.$id})`,
363
+ value: database.$id
364
+ }
365
+ })
366
+
367
+ if (choices.length === 0) {
368
+ throw new Error("No databases found. Please create one in project console.")
369
+ }
370
+
371
+ return choices;
372
+ },
373
+ when: (answers) => (answers.method ?? '').toLowerCase() === 'existing'
374
+ },
375
+ {
376
+ type: "input",
377
+ name: "databaseName",
378
+ message: "What would you like to name your database?",
379
+ default: "My Awesome Database",
380
+ when: (answers) => (answers.method ?? '').toLowerCase() !== 'existing'
381
+ },
382
+ {
383
+ type: "input",
384
+ name: "databaseId",
385
+ message: "What ID would you like to have for your database?",
386
+ default: "unique()",
387
+ when: (answers) => (answers.method ?? '').toLowerCase() !== 'existing'
388
+ },
389
+ {
390
+ type: "input",
391
+ name: "collection",
392
+ message: "What would you like to name your collection?",
393
+ default: "My Awesome Collection"
394
+ },
395
+ {
396
+ type: "input",
397
+ name: "id",
398
+ message: "What ID would you like to have for your collection?",
399
+ default: "unique()"
400
+ },
401
+ {
402
+ type: "list",
403
+ name: "documentSecurity",
404
+ message: "Enable Document-Security for configuring permissions for individual documents",
405
+ choices: ["No", "Yes"]
406
+ }
407
+ ];
408
+
409
+ const questionsCreateMessagingTopic = [
410
+ {
411
+ type: "input",
412
+ name: "topic",
413
+ message: "What would you like to name your messaging topic?",
414
+ default: "My Awesome Topic"
415
+ },
416
+ {
417
+ type: "input",
418
+ name: "id",
419
+ message: "What ID would you like to have for your messaging topic?",
420
+ default: "unique()"
421
+ }
422
+ ];
423
+
424
+ const questionsPullCollection = [
230
425
  {
231
426
  type: "checkbox",
232
427
  name: "databases",
233
- message: "From which database would you like to init collections?",
428
+ message: "From which database would you like to pull collections?",
429
+ validate: (value) => validateRequired('collection', value),
234
430
  choices: async () => {
235
431
  let response = await databasesList({
236
432
  parseOutput: false
@@ -252,6 +448,16 @@ const questionsInitCollection = [
252
448
  ];
253
449
 
254
450
  const questionsLogin = [
451
+ {
452
+ type: "list",
453
+ name: "method",
454
+ message: "You're already logged in, what you like to do?",
455
+ choices: [
456
+ { name: 'Login to a different account', value: 'login' },
457
+ { name: 'Change to a different existed account', value: 'select' }
458
+ ],
459
+ when: () => globalConfig.getCurrentSession() !== ''
460
+ },
255
461
  {
256
462
  type: "input",
257
463
  name: "email",
@@ -262,6 +468,7 @@ const questionsLogin = [
262
468
  }
263
469
  return true;
264
470
  },
471
+ when: (answers) => answers.method !== 'select'
265
472
  },
266
473
  {
267
474
  type: "password",
@@ -273,20 +480,132 @@ const questionsLogin = [
273
480
  return "Please enter your password";
274
481
  }
275
482
  return true;
276
- }
483
+ },
484
+ when: (answers) => answers.method !== 'select'
485
+ },
486
+ {
487
+ type: "search-list",
488
+ name: "accountId",
489
+ message: "Select an account to use",
490
+ choices() {
491
+ const sessions = globalConfig.getSessions();
492
+ const current = globalConfig.getCurrentSession();
493
+
494
+ const data = [];
495
+
496
+ const longestEmail = sessions.reduce((prev, current) => (prev && (prev.email ?? '').length > (current.email ?? '').length) ? prev : current).email.length;
497
+
498
+ sessions.forEach((session) => {
499
+ if (session.email) {
500
+ data.push({
501
+ current: current === session.id,
502
+ value: session.id,
503
+ name: `${session.email.padEnd(longestEmail)} ${current === session.id ? chalk.green.bold('current') : ' '.repeat(6)} ${session.endpoint}`,
504
+ });
505
+ }
506
+ })
507
+
508
+ return data.sort((a, b) => Number(b.current) - Number(a.current))
509
+ },
510
+ when: (answers) => answers.method === 'select'
277
511
  },
278
512
  ];
513
+ const questionGetEndpoint = [
514
+ {
515
+ type: "input",
516
+ name: "endpoint",
517
+ message: "Enter the endpoint of your Appwrite server",
518
+ default: "http://localhost/v1",
519
+ async validate(value) {
520
+ if (!value) {
521
+ return "Please enter a valid endpoint.";
522
+ }
523
+ let client = new Client().setEndpoint(value);
524
+ try {
525
+ let response = await client.call('get', '/health/version');
526
+ if (response.version) {
527
+ return true;
528
+ } else {
529
+ throw new Error();
530
+ }
531
+ } catch (error) {
532
+ return "Invalid endpoint or your Appwrite server is not running as expected.";
533
+ }
534
+ }
535
+ }
536
+ ];
279
537
 
280
- const questionsDeployFunctions = [
538
+ const questionsLogout = [
539
+ {
540
+ type: "checkbox",
541
+ name: "accounts",
542
+ message: "Select accounts to logout from",
543
+ validate: (value) => validateRequired('account', value),
544
+ choices() {
545
+ const sessions = globalConfig.getSessions();
546
+ const current = globalConfig.getCurrentSession();
547
+
548
+ const data = [];
549
+
550
+ const longestEmail = sessions.reduce((prev, current) => (prev && (prev.email ?? '').length > (current.email ?? '').length) ? prev : current).email.length;
551
+
552
+ sessions.forEach((session) => {
553
+ if (session.email) {
554
+ data.push({
555
+ current: current === session.id,
556
+ value: session.id,
557
+ name: `${session.email.padEnd(longestEmail)} ${current === session.id ? chalk.green.bold('current') : ' '.repeat(6)} ${session.endpoint}`,
558
+ });
559
+ }
560
+ })
561
+
562
+ return data.sort((a, b) => Number(b.current) - Number(a.current))
563
+ }
564
+ }
565
+ ];
566
+
567
+ const questionsPushResources = [
568
+ {
569
+ type: "list",
570
+ name: "resource",
571
+ message: "Which resources would you like to push?",
572
+ choices: [
573
+ { name: 'Project', value: 'project' },
574
+ { name: 'Functions', value: 'functions' },
575
+ { name: 'Collections', value: 'collections' },
576
+ { name: 'Buckets', value: 'buckets' },
577
+ { name: 'Teams', value: 'teams' },
578
+ { name: 'Topics', value: 'messages' }
579
+ ]
580
+ }
581
+ ];
582
+
583
+ const questionsInitResources = [
584
+ {
585
+ type: "list",
586
+ name: "resource",
587
+ message: "Which resource would you create?",
588
+ choices: [
589
+ { name: 'Function', value: 'function' },
590
+ { name: 'Collection', value: 'collection' },
591
+ { name: 'Bucket', value: 'bucket' },
592
+ { name: 'Team', value: 'team' },
593
+ { name: 'Topic', value: 'message' }
594
+ ]
595
+ }
596
+ ];
597
+
598
+ const questionsPushFunctions = [
281
599
  {
282
600
  type: "checkbox",
283
601
  name: "functions",
284
- message: "Which functions would you like to deploy?",
602
+ message: "Which functions would you like to push?",
603
+ validate: (value) => validateRequired('function', value),
285
604
  choices: () => {
286
605
  let functions = localConfig.getFunctions();
287
606
  checkDeployConditions(localConfig)
288
607
  if (functions.length === 0) {
289
- throw new Error("No functions found in the current directory.");
608
+ throw new Error("No functions found in the current directory Use 'appwrite pull functions' to synchronize existing one, or use 'appwrite init function' to create a new one.");
290
609
  }
291
610
  let choices = functions.map((func, idx) => {
292
611
  return {
@@ -304,17 +623,18 @@ const questionsDeployFunctions = [
304
623
  },
305
624
  ]
306
625
 
307
- const questionsDeployCollections = [
626
+ const questionsPushCollections = [
308
627
  {
309
628
  type: "checkbox",
310
629
  name: "collections",
311
- message: "Which collections would you like to deploy?",
630
+ message: "Which collections would you like to push?",
631
+ validate: (value) => validateRequired('collection', value),
312
632
  choices: () => {
313
633
  let collections = localConfig.getCollections();
314
634
  checkDeployConditions(localConfig)
315
635
 
316
636
  if (collections.length === 0) {
317
- throw new Error("No collections found in the current directory. Run `appwrite init collection` to fetch all your collections.");
637
+ throw new Error("No collections found in the current directory. Use 'appwrite pull collections' to synchronize existing one, or use 'appwrite init collection' to create a new one.");
318
638
  }
319
639
  return collections.map(collection => {
320
640
  return {
@@ -326,21 +646,22 @@ const questionsDeployCollections = [
326
646
  },
327
647
  {
328
648
  type: "input",
329
- name: "override",
330
- message: 'Are you sure you want to override this collection? This can lead to loss of data! Type "YES" to confirm.'
331
- },
649
+ name: "changes",
650
+ message: `Would you like to apply these changes? Type "YES" to confirm.`
651
+ }
332
652
  ]
333
653
 
334
- const questionsDeployBuckets = [
654
+ const questionsPushBuckets = [
335
655
  {
336
656
  type: "checkbox",
337
657
  name: "buckets",
338
- message: "Which buckets would you like to deploy?",
658
+ message: "Which buckets would you like to push?",
659
+ validate: (value) => validateRequired('bucket', value),
339
660
  choices: () => {
340
661
  let buckets = localConfig.getBuckets();
341
662
  checkDeployConditions(localConfig)
342
663
  if (buckets.length === 0) {
343
- throw new Error("No buckets found in the current directory. Run `appwrite init bucket` to fetch all your buckets.");
664
+ throw new Error("No buckets found in the current directory. Use 'appwrite pull buckets' to synchronize existing one, or use 'appwrite init bucket' to create a new one.");
344
665
  }
345
666
  return buckets.map(bucket => {
346
667
  return {
@@ -349,12 +670,32 @@ const questionsDeployBuckets = [
349
670
  }
350
671
  });
351
672
  }
673
+ }
674
+ ]
675
+
676
+ const questionsPushMessagingTopics = [
677
+ {
678
+ type: "checkbox",
679
+ name: "topics",
680
+ message: "Which messaging topic would you like to push?",
681
+ choices: () => {
682
+ let topics = localConfig.getMessagingTopics();
683
+ if (topics.length === 0) {
684
+ throw new Error("No topics found in the current directory. Use 'appwrite pull topics' to synchronize existing one, or use 'appwrite init topic' to create a new one.");
685
+ }
686
+ return topics.map(topic => {
687
+ return {
688
+ name: `${topic.name} (${topic['$id']})`,
689
+ value: topic.$id
690
+ }
691
+ });
692
+ }
352
693
  },
353
694
  {
354
695
  type: "input",
355
696
  name: "override",
356
- message: 'Are you sure you want to override this bucket? This can lead to loss of data! Type "YES" to confirm.'
357
- },
697
+ message: 'Would you like to override existing topics? This can lead to loss of data! Type "YES" to confirm.'
698
+ }
358
699
  ]
359
700
 
360
701
  const questionsGetEntrypoint = [
@@ -372,16 +713,17 @@ const questionsGetEntrypoint = [
372
713
  },
373
714
  ]
374
715
 
375
- const questionsDeployTeams = [
716
+ const questionsPushTeams = [
376
717
  {
377
718
  type: "checkbox",
378
719
  name: "teams",
379
- message: "Which teams would you like to deploy?",
720
+ message: "Which teams would you like to push?",
721
+ validate: (value) => validateRequired('team', value),
380
722
  choices: () => {
381
723
  let teams = localConfig.getTeams();
382
724
  checkDeployConditions(localConfig);
383
725
  if (teams.length === 0) {
384
- throw new Error("No teams found in the current directory. Run `appwrite init team` to fetch all your teams.");
726
+ throw new Error("No teams found in the current directory. Use 'appwrite pull teams' to synchronize existing one, or use 'appwrite init team' to create a new one.");
385
727
  }
386
728
  return teams.map(team => {
387
729
  return {
@@ -391,43 +733,38 @@ const questionsDeployTeams = [
391
733
  });
392
734
  }
393
735
  },
394
- {
395
- type: "input",
396
- name: "override",
397
- message: 'Are you sure you want to override this team? This can lead to loss of data! Type "YES" to confirm.'
398
- },
399
736
  ];
400
737
 
401
738
  const questionsListFactors = [
402
739
  {
403
740
  type: "list",
404
741
  name: "factor",
405
- message: "Your account is protected by multiple factors. Which factor would you like to use to authenticate?",
742
+ message: "Your account is protected by multi-factor authentication. Please choose one for verification.",
406
743
  choices: async () => {
407
744
  let client = await sdkForConsole(false);
408
745
  const factors = await accountListMfaFactors({
409
746
  sdk: client,
410
747
  parseOutput: false
411
748
  });
412
-
749
+
413
750
  const choices = [
414
751
  {
415
- name: `TOTP (Time-based One-time Password)`,
752
+ name: `Authenticator app (Get a code from a third-party authenticator app)`,
416
753
  value: 'totp'
417
754
  },
418
755
  {
419
- name: `E-mail`,
756
+ name: `Email (Get a security code at your Appwrite email address)`,
420
757
  value: 'email'
421
758
  },
422
759
  {
423
- name: `Phone (SMS)`,
760
+ name: `SMS (Get a security code on your Appwrite phone number)`,
424
761
  value: 'phone'
425
762
  },
426
763
  {
427
- name: `Recovery code`,
764
+ name: `Recovery code (Use one of your recovery codes for verification)`,
428
765
  value: 'recoveryCode'
429
766
  }
430
- ].filter((ch) => factors[ch.value] === true);
767
+ ].filter((ch) => factors[ch.value] === true);
431
768
 
432
769
  return choices;
433
770
  }
@@ -448,16 +785,51 @@ const questionsMfaChallenge = [
448
785
  }
449
786
  ];
450
787
 
788
+ const questionsRunFunctions = [
789
+ {
790
+ type: "list",
791
+ name: "function",
792
+ message: "Which function would you like to develop locally?",
793
+ validate: (value) => validateRequired('function', value),
794
+ choices: () => {
795
+ let functions = localConfig.getFunctions();
796
+ if (functions.length === 0) {
797
+ throw new Error("No functions found in the current directory. Use 'appwrite pull functions' to synchronize existing one, or use 'appwrite init function' to create a new one.");
798
+ }
799
+ let choices = functions.map((func, idx) => {
800
+ return {
801
+ name: `${func.name} (${func.$id})`,
802
+ value: func.$id
803
+ }
804
+ })
805
+ return choices;
806
+ }
807
+ }
808
+ ];
809
+
451
810
  module.exports = {
452
811
  questionsInitProject,
812
+ questionsCreateFunction,
813
+ questionsCreateFunctionSelectTemplate,
814
+ questionsCreateBucket,
815
+ questionsCreateCollection,
816
+ questionsCreateMessagingTopic,
817
+ questionsPullFunctions,
453
818
  questionsLogin,
454
- questionsInitFunction,
455
- questionsInitCollection,
456
- questionsDeployFunctions,
457
- questionsDeployCollections,
458
- questionsDeployBuckets,
459
- questionsDeployTeams,
819
+ questionsPullResources,
820
+ questionsLogout,
821
+ questionsPullCollection,
822
+ questionsPushResources,
823
+ questionsPushFunctions,
824
+ questionsPushCollections,
825
+ questionsPushBuckets,
826
+ questionsPushMessagingTopics,
827
+ questionsPushTeams,
460
828
  questionsGetEntrypoint,
461
829
  questionsListFactors,
462
- questionsMfaChallenge
830
+ questionsMfaChallenge,
831
+ questionsRunFunctions,
832
+ questionGetEndpoint,
833
+ questionsInitResources,
834
+ questionsCreateTeam
463
835
  };