appwrite-utils-cli 0.10.2 → 0.10.4

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
@@ -147,6 +147,8 @@ This updated CLI ensures that developers have robust tools at their fingertips t
147
147
 
148
148
  ## Changelog
149
149
 
150
+ - 0.10.04: Fixed stupid progress bar not updating -- also fixed double text
151
+ - 0.10.03: Fixed `syncDb` to push the configurations properly, accidentally hurt it during `synchronizeConfigurations`
150
152
  - 0.10.02: Updated `wipeCollection` to handle errors gracefully
151
153
  - 0.10.01: Fixed `predeployCommands` to work
152
154
  - 0.10.001: Updated `deployFunction` to not updateConfig if it's already present
@@ -47,25 +47,33 @@ export const deployFunction = async (client, functionId, codePath, activate = tr
47
47
  const fileObject = InputFile.fromBuffer(new Uint8Array(fileBuffer), `function-${functionId}.tar.gz`);
48
48
  try {
49
49
  console.log(chalk.blue("🚀 Creating deployment..."));
50
+ // Start with 1 as default total since we don't know the chunk size yet
50
51
  progressBar.start(1, 0);
51
52
  const functionResponse = await functions.createDeployment(functionId, fileObject, activate, entrypoint, commands, (progress) => {
52
53
  const chunks = progress.chunksUploaded;
53
54
  const total = progress.chunksTotal;
54
- if (chunks !== undefined && total) {
55
- if (chunks === 0 && total !== 0) {
56
- progressBar.start(total, 0);
55
+ if (chunks !== undefined && total !== undefined) {
56
+ // First chunk, initialize the bar with correct total
57
+ if (chunks === 0) {
58
+ progressBar.start(total || 100, 0);
57
59
  }
58
60
  else {
59
61
  progressBar.update(chunks);
62
+ // Check if upload is complete
60
63
  if (chunks === total) {
64
+ progressBar.update(total);
61
65
  progressBar.stop();
62
66
  console.log(chalk.green("✅ Upload complete!"));
63
67
  }
64
68
  }
65
69
  }
66
70
  });
71
+ // Ensure progress bar completes even if callback never fired
72
+ if (progressBar.getProgress() === 0) {
73
+ progressBar.update(1);
74
+ progressBar.stop();
75
+ }
67
76
  await fs.promises.unlink(tarPath);
68
- console.log(chalk.green("✨ Function deployed successfully!"));
69
77
  return functionResponse;
70
78
  }
71
79
  catch (error) {
@@ -118,7 +118,7 @@ export class InteractiveCLI {
118
118
  break;
119
119
  case CHOICES.EXIT:
120
120
  console.log(chalk.green("Goodbye!"));
121
- return;
121
+ process.exit(0);
122
122
  }
123
123
  }
124
124
  }
@@ -388,7 +388,6 @@ export class InteractiveCLI {
388
388
  console.log(chalk.yellow(`Function not found in primary location, searching subdirectories...`));
389
389
  const foundPath = await this.findFunctionInSubdirectories(this.controller.getAppwriteFolderPath(), functionConfig.name.toLowerCase());
390
390
  if (foundPath) {
391
- console.log(chalk.green(`Found function at: ${foundPath}`));
392
391
  functionPath = foundPath;
393
392
  functionConfig.dirPath = foundPath;
394
393
  }
@@ -718,28 +717,46 @@ export class InteractiveCLI {
718
717
  }, bucketId.length > 0 ? bucketId : ulid());
719
718
  }
720
719
  async syncDb() {
721
- console.log(chalk.yellow("Syncing database..."));
722
- const functionsClient = new Functions(this.controller.appwriteServer);
723
- const databases = await this.selectDatabases(await fetchAllDatabases(this.controller.database), chalk.blue("Select databases to synchronize:"), true);
724
- const collections = await this.selectCollections(databases[0], this.controller.database, chalk.blue("Select collections to synchronize:"), true, true // prefer local
720
+ console.log(chalk.blue("Pushing local configuration to Appwrite..."));
721
+ const databases = await this.selectDatabases(this.getLocalDatabases(), chalk.blue("Select local databases to push:"), true);
722
+ if (!databases.length) {
723
+ console.log(chalk.yellow("No databases selected. Skipping database sync."));
724
+ return;
725
+ }
726
+ const collections = await this.selectCollections(databases[0], this.controller.database, chalk.blue("Select local collections to push:"), true, true // prefer local
725
727
  );
726
- const answer = await inquirer.prompt([
728
+ const { syncFunctions } = await inquirer.prompt([
727
729
  {
728
730
  type: "confirm",
729
731
  name: "syncFunctions",
730
- message: "Do you want to synchronize functions?",
732
+ message: "Do you want to push local functions to remote?",
731
733
  default: false,
732
734
  },
733
735
  ]);
734
- if (answer.syncFunctions) {
735
- const functions = await this.selectFunctions(chalk.blue("Select functions to synchronize:"), true, true // prefer local
736
- );
736
+ try {
737
+ // First sync databases and collections
737
738
  await this.controller.syncDb(databases, collections);
738
- for (const func of functions) {
739
- await deployLocalFunction(this.controller.appwriteServer, func.dirPath || `functions/${func.name}`, func);
739
+ console.log(chalk.green("Database and collections pushed successfully"));
740
+ // Then handle functions if requested
741
+ if (syncFunctions && this.controller.config?.functions?.length) {
742
+ const functions = await this.selectFunctions(chalk.blue("Select local functions to push:"), true, true // prefer local
743
+ );
744
+ for (const func of functions) {
745
+ try {
746
+ await this.controller.deployFunction(func.name);
747
+ console.log(chalk.green(`Function ${func.name} deployed successfully`));
748
+ }
749
+ catch (error) {
750
+ console.error(chalk.red(`Failed to deploy function ${func.name}:`), error);
751
+ }
752
+ }
740
753
  }
754
+ console.log(chalk.green("Local configuration push completed successfully!"));
755
+ }
756
+ catch (error) {
757
+ console.error(chalk.red("Failed to push local configuration:"), error);
758
+ throw error;
741
759
  }
742
- console.log(chalk.green("Database sync completed."));
743
760
  }
744
761
  async synchronizeConfigurations() {
745
762
  console.log(chalk.blue("Synchronizing configurations..."));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "appwrite-utils-cli",
3
3
  "description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
4
- "version": "0.10.02",
4
+ "version": "0.10.04",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -77,7 +77,9 @@ export const deployFunction = async (
77
77
 
78
78
  try {
79
79
  console.log(chalk.blue("🚀 Creating deployment..."));
80
+ // Start with 1 as default total since we don't know the chunk size yet
80
81
  progressBar.start(1, 0);
82
+
81
83
  const functionResponse = await functions.createDeployment(
82
84
  functionId,
83
85
  fileObject,
@@ -87,12 +89,17 @@ export const deployFunction = async (
87
89
  (progress) => {
88
90
  const chunks = progress.chunksUploaded;
89
91
  const total = progress.chunksTotal;
90
- if (chunks !== undefined && total) {
91
- if (chunks === 0 && total !== 0) {
92
- progressBar.start(total, 0);
92
+
93
+ if (chunks !== undefined && total !== undefined) {
94
+ // First chunk, initialize the bar with correct total
95
+ if (chunks === 0) {
96
+ progressBar.start(total || 100, 0);
93
97
  } else {
94
98
  progressBar.update(chunks);
99
+
100
+ // Check if upload is complete
95
101
  if (chunks === total) {
102
+ progressBar.update(total);
96
103
  progressBar.stop();
97
104
  console.log(chalk.green("✅ Upload complete!"));
98
105
  }
@@ -101,8 +108,13 @@ export const deployFunction = async (
101
108
  }
102
109
  );
103
110
 
111
+ // Ensure progress bar completes even if callback never fired
112
+ if (progressBar.getProgress() === 0) {
113
+ progressBar.update(1);
114
+ progressBar.stop();
115
+ }
116
+
104
117
  await fs.promises.unlink(tarPath);
105
- console.log(chalk.green("✨ Function deployed successfully!"));
106
118
  return functionResponse;
107
119
  } catch (error) {
108
120
  progressBar.stop();
@@ -154,7 +154,7 @@ export class InteractiveCLI {
154
154
  break;
155
155
  case CHOICES.EXIT:
156
156
  console.log(chalk.green("Goodbye!"));
157
- return;
157
+ process.exit(0);
158
158
  }
159
159
  }
160
160
  }
@@ -533,7 +533,6 @@ export class InteractiveCLI {
533
533
  );
534
534
 
535
535
  if (foundPath) {
536
- console.log(chalk.green(`Found function at: ${foundPath}`));
537
536
  functionPath = foundPath;
538
537
  functionConfig.dirPath = foundPath;
539
538
  } else {
@@ -977,44 +976,73 @@ export class InteractiveCLI {
977
976
  }
978
977
 
979
978
  private async syncDb(): Promise<void> {
980
- console.log(chalk.yellow("Syncing database..."));
981
- const functionsClient = new Functions(this.controller!.appwriteServer!);
979
+ console.log(chalk.blue("Pushing local configuration to Appwrite..."));
980
+
982
981
  const databases = await this.selectDatabases(
983
- await fetchAllDatabases(this.controller!.database!),
984
- chalk.blue("Select databases to synchronize:"),
982
+ this.getLocalDatabases(),
983
+ chalk.blue("Select local databases to push:"),
985
984
  true
986
985
  );
986
+
987
+ if (!databases.length) {
988
+ console.log(
989
+ chalk.yellow("No databases selected. Skipping database sync.")
990
+ );
991
+ return;
992
+ }
993
+
987
994
  const collections = await this.selectCollections(
988
995
  databases[0],
989
996
  this.controller!.database!,
990
- chalk.blue("Select collections to synchronize:"),
997
+ chalk.blue("Select local collections to push:"),
991
998
  true,
992
999
  true // prefer local
993
1000
  );
994
- const answer = await inquirer.prompt([
1001
+
1002
+ const { syncFunctions } = await inquirer.prompt([
995
1003
  {
996
1004
  type: "confirm",
997
1005
  name: "syncFunctions",
998
- message: "Do you want to synchronize functions?",
1006
+ message: "Do you want to push local functions to remote?",
999
1007
  default: false,
1000
1008
  },
1001
1009
  ]);
1002
- if (answer.syncFunctions) {
1003
- const functions = await this.selectFunctions(
1004
- chalk.blue("Select functions to synchronize:"),
1005
- true,
1006
- true // prefer local
1007
- );
1010
+
1011
+ try {
1012
+ // First sync databases and collections
1008
1013
  await this.controller!.syncDb(databases, collections);
1009
- for (const func of functions) {
1010
- await deployLocalFunction(
1011
- this.controller!.appwriteServer!,
1012
- func.dirPath || `functions/${func.name}`,
1013
- func
1014
+ console.log(chalk.green("Database and collections pushed successfully"));
1015
+
1016
+ // Then handle functions if requested
1017
+ if (syncFunctions && this.controller!.config?.functions?.length) {
1018
+ const functions = await this.selectFunctions(
1019
+ chalk.blue("Select local functions to push:"),
1020
+ true,
1021
+ true // prefer local
1014
1022
  );
1023
+
1024
+ for (const func of functions) {
1025
+ try {
1026
+ await this.controller!.deployFunction(func.name);
1027
+ console.log(
1028
+ chalk.green(`Function ${func.name} deployed successfully`)
1029
+ );
1030
+ } catch (error) {
1031
+ console.error(
1032
+ chalk.red(`Failed to deploy function ${func.name}:`),
1033
+ error
1034
+ );
1035
+ }
1036
+ }
1015
1037
  }
1038
+
1039
+ console.log(
1040
+ chalk.green("Local configuration push completed successfully!")
1041
+ );
1042
+ } catch (error) {
1043
+ console.error(chalk.red("Failed to push local configuration:"), error);
1044
+ throw error;
1016
1045
  }
1017
- console.log(chalk.green("Database sync completed."));
1018
1046
  }
1019
1047
 
1020
1048
  private async synchronizeConfigurations(): Promise<void> {