appwrite-cli 5.0.2 → 5.0.5

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
@@ -1,7 +1,7 @@
1
1
  # Appwrite Command Line SDK
2
2
 
3
3
  ![License](https://img.shields.io/github/license/appwrite/sdk-for-cli.svg?style=flat-square)
4
- ![Version](https://img.shields.io/badge/api%20version-1.5.4-blue.svg?style=flat-square)
4
+ ![Version](https://img.shields.io/badge/api%20version-1.5.6-blue.svg?style=flat-square)
5
5
  [![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
6
6
  [![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
7
7
  [![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
@@ -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
- 5.0.2
32
+ 5.0.5
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
- 5.0.2
63
+ 5.0.5
64
64
  ```
65
65
 
66
66
  ## Getting Started
@@ -10,3 +10,4 @@ appwrite messaging updateEmail \
10
10
 
11
11
 
12
12
 
13
+
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/5.0.2/appwrite-cli-win-x64.exe"
17
- $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/5.0.2/appwrite-cli-win-arm64.exe"
16
+ $GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/5.0.5/appwrite-cli-win-x64.exe"
17
+ $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/5.0.5/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="5.0.2"
100
+ GITHUB_LATEST_VERSION="5.0.5"
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
@@ -15,8 +15,8 @@ class Client {
15
15
  'x-sdk-name': 'Command Line',
16
16
  'x-sdk-platform': 'console',
17
17
  'x-sdk-language': 'cli',
18
- 'x-sdk-version': '5.0.2',
19
- 'user-agent' : `AppwriteCLI/5.0.2 (${os.type()} ${os.version()}; ${os.arch()})`,
18
+ 'x-sdk-version': '5.0.5',
19
+ 'user-agent' : `AppwriteCLI/5.0.5 (${os.type()} ${os.version()}; ${os.arch()})`,
20
20
  'X-Appwrite-Response-Format' : '1.5.0',
21
21
  };
22
22
  }
@@ -204,7 +204,7 @@ class Client {
204
204
 
205
205
  let cookies = response.headers.getSetCookie();
206
206
  if (cookies && cookies.length > 0) {
207
- globalConfig.setCookie(cookies[0]);
207
+ globalConfig.setCookie(cookies.join(";"));
208
208
  }
209
209
 
210
210
  const text = await response.text();
@@ -235,4 +235,4 @@ class Client {
235
235
  }
236
236
  }
237
237
 
238
- module.exports = Client;
238
+ module.exports = Client;
@@ -1679,13 +1679,13 @@ account
1679
1679
 
1680
1680
  account
1681
1681
  .command(`createMfaAuthenticator`)
1682
- .description(`Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#verifyAuthenticator) method.`)
1682
+ .description(`Add an authenticator app to be used as an MFA factor. Verify the authenticator using the [verify authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator) method.`)
1683
1683
  .requiredOption(`--type <type>`, `Type of authenticator. Must be 'totp'`)
1684
1684
  .action(actionRunner(accountCreateMfaAuthenticator))
1685
1685
 
1686
1686
  account
1687
1687
  .command(`updateMfaAuthenticator`)
1688
- .description(`Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#addAuthenticator) method.`)
1688
+ .description(`Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method. add `)
1689
1689
  .requiredOption(`--type <type>`, `Type of authenticator.`)
1690
1690
  .requiredOption(`--otp <otp>`, `Valid verification token.`)
1691
1691
  .action(actionRunner(accountUpdateMfaAuthenticator))
@@ -89,7 +89,7 @@ const avatarsGetBrowser = async ({ code, width, height, quality, parseOutput = t
89
89
 
90
90
  /**
91
91
  * @typedef {Object} AvatarsGetCreditCardRequestParams
92
- * @property {CreditCard} 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.
92
+ * @property {CreditCard} code Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.
93
93
  * @property {number} width Image width. Pass an integer between 0 to 2000. Defaults to 100.
94
94
  * @property {number} height Image height. Pass an integer between 0 to 2000. Defaults to 100.
95
95
  * @property {number} quality Image quality. Pass an integer between 0 to 100. Defaults to 100.
@@ -384,7 +384,7 @@ avatars
384
384
  avatars
385
385
  .command(`getCreditCard`)
386
386
  .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. When one dimension is specified and the other is 0, the image is scaled with preserved aspect ratio. If both dimensions are 0, the API provides an image at source quality. If dimensions are not specified, the default size of image returned is 100x100px. `)
387
- .requiredOption(`--code <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.`)
387
+ .requiredOption(`--code <code>`, `Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro.`)
388
388
  .option(`--width <width>`, `Image width. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
389
389
  .option(`--height <height>`, `Image height. Pass an integer between 0 to 2000. Defaults to 100.`, parseInteger)
390
390
  .option(`--quality <quality>`, `Image quality. Pass an integer between 0 to 100. Defaults to 100.`, parseInteger)
@@ -34,9 +34,10 @@ const {
34
34
  } = require("./storage");
35
35
  const {
36
36
  teamsGet,
37
- teamsUpdate,
37
+ teamsUpdateName,
38
38
  teamsCreate
39
39
  } = require("./teams");
40
+ const { checkDeployConditions } = require('../utils');
40
41
 
41
42
  const STEP_SIZE = 100; // Resources
42
43
  const POOL_DEBOUNCE = 2000; // Milliseconds
@@ -245,6 +246,7 @@ const deployFunction = async ({ functionId, all, yes } = {}) => {
245
246
  functionIds.push(functionId);
246
247
  } else if (all) {
247
248
  const functions = localConfig.getFunctions();
249
+ checkDeployConditions(localConfig);
248
250
  if (functions.length === 0) {
249
251
  throw new Error("No functions found in the current directory.");
250
252
  }
@@ -353,7 +355,7 @@ const deployFunction = async ({ functionId, all, yes } = {}) => {
353
355
  functionId: func['$id'],
354
356
  parseOutput: false
355
357
  }, 100, 'variables');
356
-
358
+
357
359
  await Promise.all(variables.map(async variable => {
358
360
  await functionsDeleteVariable({
359
361
  functionId: func['$id'],
@@ -361,7 +363,7 @@ const deployFunction = async ({ functionId, all, yes } = {}) => {
361
363
  parseOutput: false
362
364
  });
363
365
  }));
364
-
366
+
365
367
  let result = await awaitPools.wipeVariables(func['$id']);
366
368
  if (!result) {
367
369
  throw new Error("Variable deletion timed out.");
@@ -535,6 +537,7 @@ const deployCollection = async ({ all, yes } = {}) => {
535
537
  const collections = [];
536
538
 
537
539
  if (all) {
540
+ checkDeployConditions(localConfig);
538
541
  if (localConfig.getCollections().length === 0) {
539
542
  throw new Error("No collections found in the current directory. Run `appwrite init collection` to fetch all your collections.");
540
543
  }
@@ -757,9 +760,7 @@ const deployBucket = async ({ all, yes } = {}) => {
757
760
  const configBuckets = localConfig.getBuckets();
758
761
 
759
762
  if (all) {
760
- if (configBuckets.length === 0) {
761
- throw new Error("No buckets found in the current directory. Run `appwrite init bucket` to fetch all your buckets.");
762
- }
763
+ checkDeployConditions(localConfig);
763
764
  bucketIds.push(...configBuckets.map((b) => b.$id));
764
765
  }
765
766
 
@@ -844,9 +845,7 @@ const deployTeam = async ({ all, yes } = {}) => {
844
845
  const configTeams = localConfig.getTeams();
845
846
 
846
847
  if (all) {
847
- if (configTeams.length === 0) {
848
- throw new Error("No teams found in the current directory. Run `appwrite init team` to fetch all your teams.");
849
- }
848
+ checkDeployConditions(localConfig);
850
849
  teamIds.push(...configTeams.map((t) => t.$id));
851
850
  }
852
851
 
@@ -882,7 +881,7 @@ const deployTeam = async ({ all, yes } = {}) => {
882
881
 
883
882
  log(`Updating team ...`)
884
883
 
885
- await teamsUpdate({
884
+ await teamsUpdateName({
886
885
  teamId: team['$id'],
887
886
  name: team.name,
888
887
  parseOutput: false
@@ -938,4 +937,4 @@ deploy
938
937
 
939
938
  module.exports = {
940
939
  deploy
941
- }
940
+ }
@@ -4,8 +4,8 @@ const Client = require("../client");
4
4
  const { sdkForConsole } = require("../sdks");
5
5
  const { globalConfig, localConfig } = require("../config");
6
6
  const { actionRunner, success, parseBool, commandDescriptions, log, parse } = require("../parser");
7
- const { questionsLogin } = require("../questions");
8
- const { accountCreateEmailPasswordSession, accountDeleteSession } = require("./account");
7
+ const { questionsLogin, questionsListFactors, questionsMfaChallenge } = require("../questions");
8
+ const { accountUpdateMfaChallenge, accountCreateMfaChallenge, accountGet, accountCreateEmailPasswordSession, accountDeleteSession } = require("./account");
9
9
 
10
10
  const login = new Command("login")
11
11
  .description(commandDescriptions['login'])
@@ -24,7 +24,44 @@ const login = new Command("login")
24
24
  sdk: client
25
25
  })
26
26
 
27
- success()
27
+ client.setCookie(globalConfig.getCookie());
28
+
29
+ let account;
30
+
31
+ try {
32
+ account = await accountGet({
33
+ sdk: client,
34
+ parseOutput: false
35
+ });
36
+ } catch(error) {
37
+ if (error.response === 'user_more_factors_required') {
38
+ const { factor } = await inquirer.prompt(questionsListFactors);
39
+
40
+ const challenge = await accountCreateMfaChallenge({
41
+ factor,
42
+ parseOutput: false,
43
+ sdk: client
44
+ });
45
+
46
+ const { otp } = await inquirer.prompt(questionsMfaChallenge);
47
+
48
+ await accountUpdateMfaChallenge({
49
+ challengeId: challenge.$id,
50
+ otp,
51
+ parseOutput: false,
52
+ sdk: client
53
+ });
54
+
55
+ account = await accountGet({
56
+ sdk: client,
57
+ parseOutput: false
58
+ });
59
+ } else {
60
+ throw error;
61
+ }
62
+ }
63
+
64
+ success("Signed in as user with ID: " + account.$id);
28
65
  }));
29
66
 
30
67
  const logout = new Command("logout")
@@ -85,7 +85,7 @@ const messagingListMessages = async ({ queries, search, parseOutput = true, sdk
85
85
  * @property {string[]} targets List of Targets IDs.
86
86
  * @property {string[]} cc Array of target IDs to be added as CC.
87
87
  * @property {string[]} bcc Array of target IDs to be added as BCC.
88
- * @property {string[]} attachments Array of compound bucket IDs to file IDs to be attached to the email.
88
+ * @property {string[]} attachments Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as &lt;BUCKET_ID&gt;:&lt;FILE_ID&gt;.
89
89
  * @property {boolean} draft Is message a draft
90
90
  * @property {boolean} html Is content of type HTML
91
91
  * @property {string} scheduledAt Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.
@@ -170,6 +170,7 @@ const messagingCreateEmail = async ({ messageId, subject, content, topics, users
170
170
  * @property {string[]} cc Array of target IDs to be added as CC.
171
171
  * @property {string[]} bcc Array of target IDs to be added as BCC.
172
172
  * @property {string} scheduledAt Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.
173
+ * @property {string[]} attachments Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as &lt;BUCKET_ID&gt;:&lt;FILE_ID&gt;.
173
174
  * @property {boolean} parseOutput
174
175
  * @property {libClient | undefined} sdk
175
176
  */
@@ -177,7 +178,7 @@ const messagingCreateEmail = async ({ messageId, subject, content, topics, users
177
178
  /**
178
179
  * @param {MessagingUpdateEmailRequestParams} params
179
180
  */
180
- const messagingUpdateEmail = async ({ messageId, topics, users, targets, subject, content, draft, html, cc, bcc, scheduledAt, parseOutput = true, sdk = undefined}) => {
181
+ const messagingUpdateEmail = async ({ messageId, topics, users, targets, subject, content, draft, html, cc, bcc, scheduledAt, attachments, parseOutput = true, sdk = undefined}) => {
181
182
  let client = !sdk ? await sdkForProject() : sdk;
182
183
  let apiPath = '/messaging/messages/email/{messageId}'.replace('{messageId}', messageId);
183
184
  let payload = {};
@@ -216,6 +217,10 @@ const messagingUpdateEmail = async ({ messageId, topics, users, targets, subject
216
217
  if (typeof scheduledAt !== 'undefined') {
217
218
  payload['scheduledAt'] = scheduledAt;
218
219
  }
220
+ attachments = attachments === true ? [] : attachments;
221
+ if (typeof attachments !== 'undefined') {
222
+ payload['attachments'] = attachments;
223
+ }
219
224
 
220
225
  let response = undefined;
221
226
 
@@ -241,7 +246,7 @@ const messagingUpdateEmail = async ({ messageId, topics, users, targets, subject
241
246
  * @property {string[]} targets List of Targets IDs.
242
247
  * @property {object} data Additional Data for push notification.
243
248
  * @property {string} action Action for push notification.
244
- * @property {string} image Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage.
249
+ * @property {string} image Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as &lt;BUCKET_ID&gt;:&lt;FILE_ID&gt;.
245
250
  * @property {string} icon Icon for push notification. Available only for Android and Web Platform.
246
251
  * @property {string} sound Sound for push notification. Available only for Android and IOS Platform.
247
252
  * @property {string} color Color for push notification. Available only for Android Platform.
@@ -336,7 +341,7 @@ const messagingCreatePush = async ({ messageId, title, body, topics, users, targ
336
341
  * @property {string} body Body for push notification.
337
342
  * @property {object} data Additional Data for push notification.
338
343
  * @property {string} action Action for push notification.
339
- * @property {string} image Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage.
344
+ * @property {string} image Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as &lt;BUCKET_ID&gt;:&lt;FILE_ID&gt;.
340
345
  * @property {string} icon Icon for push notification. Available only for Android and Web platforms.
341
346
  * @property {string} sound Sound for push notification. Available only for Android and iOS platforms.
342
347
  * @property {string} color Color for push notification. Available only for Android platforms.
@@ -2297,7 +2302,7 @@ messaging
2297
2302
  .option(`--targets [targets...]`, `List of Targets IDs.`)
2298
2303
  .option(`--cc [cc...]`, `Array of target IDs to be added as CC.`)
2299
2304
  .option(`--bcc [bcc...]`, `Array of target IDs to be added as BCC.`)
2300
- .option(`--attachments [attachments...]`, `Array of compound bucket IDs to file IDs to be attached to the email.`)
2305
+ .option(`--attachments [attachments...]`, `Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as <BUCKET_ID>:<FILE_ID>.`)
2301
2306
  .option(`--draft <draft>`, `Is message a draft`, parseBool)
2302
2307
  .option(`--html <html>`, `Is content of type HTML`, parseBool)
2303
2308
  .option(`--scheduledAt <scheduledAt>`, `Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.`)
@@ -2317,6 +2322,7 @@ messaging
2317
2322
  .option(`--cc [cc...]`, `Array of target IDs to be added as CC.`)
2318
2323
  .option(`--bcc [bcc...]`, `Array of target IDs to be added as BCC.`)
2319
2324
  .option(`--scheduledAt <scheduledAt>`, `Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.`)
2325
+ .option(`--attachments [attachments...]`, `Array of compound ID strings of bucket IDs and file IDs to be attached to the email. They should be formatted as <BUCKET_ID>:<FILE_ID>.`)
2320
2326
  .action(actionRunner(messagingUpdateEmail))
2321
2327
 
2322
2328
  messaging
@@ -2330,7 +2336,7 @@ messaging
2330
2336
  .option(`--targets [targets...]`, `List of Targets IDs.`)
2331
2337
  .option(`--data <data>`, `Additional Data for push notification.`)
2332
2338
  .option(`--action <action>`, `Action for push notification.`)
2333
- .option(`--image <image>`, `Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage.`)
2339
+ .option(`--image <image>`, `Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as <BUCKET_ID>:<FILE_ID>.`)
2334
2340
  .option(`--icon <icon>`, `Icon for push notification. Available only for Android and Web Platform.`)
2335
2341
  .option(`--sound <sound>`, `Sound for push notification. Available only for Android and IOS Platform.`)
2336
2342
  .option(`--color <color>`, `Color for push notification. Available only for Android Platform.`)
@@ -2351,7 +2357,7 @@ messaging
2351
2357
  .option(`--body <body>`, `Body for push notification.`)
2352
2358
  .option(`--data <data>`, `Additional Data for push notification.`)
2353
2359
  .option(`--action <action>`, `Action for push notification.`)
2354
- .option(`--image <image>`, `Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage.`)
2360
+ .option(`--image <image>`, `Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as <BUCKET_ID>:<FILE_ID>.`)
2355
2361
  .option(`--icon <icon>`, `Icon for push notification. Available only for Android and Web platforms.`)
2356
2362
  .option(`--sound <sound>`, `Sound for push notification. Available only for Android and iOS platforms.`)
2357
2363
  .option(`--color <color>`, `Color for push notification. Available only for Android platforms.`)
@@ -1823,7 +1823,7 @@ users
1823
1823
 
1824
1824
  users
1825
1825
  .command(`createToken`)
1826
- .description(`Returns a token with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [PUT /account/sessions/custom](https://appwrite.io/docs/references/cloud/client-web/account#updateCustomSession) endpoint to complete the login process.`)
1826
+ .description(`Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT /account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. `)
1827
1827
  .requiredOption(`--userId <userId>`, `User ID.`)
1828
1828
  .option(`--length <length>`, `Token length in characters. The default length is 6 characters`, parseInteger)
1829
1829
  .option(`--expire <expire>`, `Token expiration period in seconds. The default expiration is 15 minutes.`, parseInteger)
package/lib/questions.js CHANGED
@@ -1,7 +1,11 @@
1
1
  const { localConfig } = require('./config');
2
2
  const { projectsList } = require('./commands/projects');
3
3
  const { functionsListRuntimes } = require('./commands/functions');
4
+ const { accountListMfaFactors } = require("./commands/account");
5
+ const { sdkForConsole } = require("./sdks");
6
+
4
7
  const { databasesList } = require('./commands/databases');
8
+ const { checkDeployConditions } = require('./utils');
5
9
  const JSONbig = require("json-bigint")({ storeAsString: false });
6
10
 
7
11
  const getIgnores = (runtime) => {
@@ -206,12 +210,12 @@ const questionsInitFunction = [
206
210
  parseOutput: false
207
211
  })
208
212
  let runtimes = response["runtimes"]
209
- let choices = runtimes.map((runtime, idx) => {
213
+ let choices = runtimes.map((runtime, idx) => {
210
214
  return {
211
215
  name: `${runtime.name} (${runtime['$id']})`,
212
- value: {
213
- id: runtime['$id'],
214
- entrypoint: getEntrypoint(runtime['$id']),
216
+ value: {
217
+ id: runtime['$id'],
218
+ entrypoint: getEntrypoint(runtime['$id']),
215
219
  ignore: getIgnores(runtime['$id']),
216
220
  commands : getInstallCommand(runtime['$id'])
217
221
  },
@@ -280,6 +284,7 @@ const questionsDeployFunctions = [
280
284
  message: "Which functions would you like to deploy?",
281
285
  choices: () => {
282
286
  let functions = localConfig.getFunctions();
287
+ checkDeployConditions(localConfig)
283
288
  if (functions.length === 0) {
284
289
  throw new Error("No functions found in the current directory.");
285
290
  }
@@ -306,6 +311,8 @@ const questionsDeployCollections = [
306
311
  message: "Which collections would you like to deploy?",
307
312
  choices: () => {
308
313
  let collections = localConfig.getCollections();
314
+ checkDeployConditions(localConfig)
315
+
309
316
  if (collections.length === 0) {
310
317
  throw new Error("No collections found in the current directory. Run `appwrite init collection` to fetch all your collections.");
311
318
  }
@@ -331,6 +338,7 @@ const questionsDeployBuckets = [
331
338
  message: "Which buckets would you like to deploy?",
332
339
  choices: () => {
333
340
  let buckets = localConfig.getBuckets();
341
+ checkDeployConditions(localConfig)
334
342
  if (buckets.length === 0) {
335
343
  throw new Error("No buckets found in the current directory. Run `appwrite init bucket` to fetch all your buckets.");
336
344
  }
@@ -371,6 +379,7 @@ const questionsDeployTeams = [
371
379
  message: "Which teams would you like to deploy?",
372
380
  choices: () => {
373
381
  let teams = localConfig.getTeams();
382
+ checkDeployConditions(localConfig);
374
383
  if (teams.length === 0) {
375
384
  throw new Error("No teams found in the current directory. Run `appwrite init team` to fetch all your teams.");
376
385
  }
@@ -387,7 +396,57 @@ const questionsDeployTeams = [
387
396
  name: "override",
388
397
  message: 'Are you sure you want to override this team? This can lead to loss of data! Type "YES" to confirm.'
389
398
  },
390
- ]
399
+ ];
400
+
401
+ const questionsListFactors = [
402
+ {
403
+ type: "list",
404
+ name: "factor",
405
+ message: "Your account is protected by multiple factors. Which factor would you like to use to authenticate?",
406
+ choices: async () => {
407
+ let client = await sdkForConsole(false);
408
+ const factors = await accountListMfaFactors({
409
+ sdk: client,
410
+ parseOutput: false
411
+ });
412
+
413
+ const choices = [
414
+ {
415
+ name: `TOTP (Time-based One-time Password)`,
416
+ value: 'totp'
417
+ },
418
+ {
419
+ name: `E-mail`,
420
+ value: 'email'
421
+ },
422
+ {
423
+ name: `Phone (SMS)`,
424
+ value: 'phone'
425
+ },
426
+ {
427
+ name: `Recovery code`,
428
+ value: 'recoveryCode'
429
+ }
430
+ ].filter((ch) => factors[ch.value] === true);
431
+
432
+ return choices;
433
+ }
434
+ }
435
+ ];
436
+
437
+ const questionsMfaChallenge = [
438
+ {
439
+ type: "input",
440
+ name: "otp",
441
+ message: "Enter OTP",
442
+ validate(value) {
443
+ if (!value) {
444
+ return "Please enter OTP";
445
+ }
446
+ return true;
447
+ },
448
+ }
449
+ ];
391
450
 
392
451
  module.exports = {
393
452
  questionsInitProject,
@@ -398,5 +457,7 @@ module.exports = {
398
457
  questionsDeployCollections,
399
458
  questionsDeployBuckets,
400
459
  questionsDeployTeams,
401
- questionsGetEntrypoint
460
+ questionsGetEntrypoint,
461
+ questionsListFactors,
462
+ questionsMfaChallenge
402
463
  };
package/lib/utils.js CHANGED
@@ -14,6 +14,13 @@ function getAllFiles(folder) {
14
14
  return files;
15
15
  }
16
16
 
17
+ const checkDeployConditions = (localConfig) => {
18
+ if (Object.keys(localConfig.data).length === 0) {
19
+ throw new Error("No appwrite.json file found in the current directory. This command must be run in the folder holding your appwrite.json file. Please run this command again in the folder containing your appwrite.json file, or run appwrite init project.");
20
+ }
21
+ }
22
+
17
23
  module.exports = {
18
- getAllFiles
24
+ getAllFiles,
25
+ checkDeployConditions
19
26
  };
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": "5.0.2",
5
+ "version": "5.0.5",
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": "5.0.2",
3
+ "version": "5.0.5",
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/5.0.2/appwrite-cli-win-x64.exe",
9
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/5.0.5/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/5.0.2/appwrite-cli-win-arm64.exe",
18
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/5.0.5/appwrite-cli-win-arm64.exe",
19
19
  "bin": [
20
20
  [
21
21
  "appwrite-cli-win-arm64.exe",