appwrite-cli 5.0.3 → 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 (54) 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/messaging/update-email.md +1 -0
  9. package/docs/examples/projects/create-j-w-t.md +4 -0
  10. package/docs/examples/projects/update-mock-numbers.md +3 -0
  11. package/docs/examples/projects/update-session-alerts.md +3 -0
  12. package/docs/examples/users/create-j-w-t.md +4 -0
  13. package/docs/examples/vcs/get-repository-contents.md +4 -0
  14. package/index.js +34 -7
  15. package/install.ps1 +3 -3
  16. package/install.sh +2 -2
  17. package/lib/client.js +19 -5
  18. package/lib/commands/account.js +307 -153
  19. package/lib/commands/assistant.js +8 -5
  20. package/lib/commands/avatars.js +116 -60
  21. package/lib/commands/console.js +8 -5
  22. package/lib/commands/databases.js +353 -164
  23. package/lib/commands/functions.js +310 -100
  24. package/lib/commands/generic.js +206 -54
  25. package/lib/commands/graphql.js +14 -8
  26. package/lib/commands/health.js +140 -71
  27. package/lib/commands/init.js +250 -155
  28. package/lib/commands/locale.js +50 -26
  29. package/lib/commands/messaging.js +363 -179
  30. package/lib/commands/migrations.js +98 -50
  31. package/lib/commands/project.js +38 -20
  32. package/lib/commands/projects.js +449 -144
  33. package/lib/commands/proxy.js +32 -17
  34. package/lib/commands/pull.js +231 -0
  35. package/lib/commands/push.js +1518 -0
  36. package/lib/commands/run.js +282 -0
  37. package/lib/commands/storage.js +160 -76
  38. package/lib/commands/teams.js +102 -50
  39. package/lib/commands/users.js +325 -135
  40. package/lib/commands/vcs.js +102 -29
  41. package/lib/config.js +190 -18
  42. package/lib/emulation/docker.js +187 -0
  43. package/lib/emulation/utils.js +177 -0
  44. package/lib/id.js +30 -0
  45. package/lib/paginate.js +1 -2
  46. package/lib/parser.js +69 -12
  47. package/lib/questions.js +462 -84
  48. package/lib/sdks.js +1 -1
  49. package/lib/spinner.js +103 -0
  50. package/lib/utils.js +248 -3
  51. package/lib/validations.js +17 -0
  52. package/package.json +6 -2
  53. package/scoop/appwrite.json +3 -3
  54. package/lib/commands/deploy.js +0 -941
package/lib/sdks.js CHANGED
@@ -68,7 +68,7 @@ const sdkForProject = async () => {
68
68
  }
69
69
 
70
70
  if (!project) {
71
- throw new Error("Project is not set. Please run `appwrite init project` to initialize the current directory with an Appwrite project.");
71
+ throw new Error("Project is not set. Please run `appwrite init` to initialize the current directory with an Appwrite project.");
72
72
  }
73
73
 
74
74
  client
package/lib/spinner.js ADDED
@@ -0,0 +1,103 @@
1
+ const progress = require('cli-progress');
2
+ const chalk = require('chalk');
3
+
4
+ const SPINNER_ARC = 'arc';
5
+ const SPINNER_DOTS = 'dots';
6
+
7
+ const spinners = {
8
+ [SPINNER_ARC]: {
9
+ "interval": 100,
10
+ "frames": ["◜", "◠", "◝", "◞", "◡", "◟"]
11
+ },
12
+ [SPINNER_DOTS]: {
13
+ "interval": 80,
14
+ "frames": ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
15
+ }
16
+ }
17
+
18
+ class Spinner {
19
+ static start(clearOnComplete = true, hideCursor = true) {
20
+ Spinner.updatesBar = new progress.MultiBar({
21
+ format: this.#formatter,
22
+ hideCursor,
23
+ clearOnComplete,
24
+ stopOnComplete: true,
25
+ noTTYOutput: true
26
+ });
27
+ }
28
+
29
+ static stop() {
30
+ Spinner.updatesBar.stop();
31
+ }
32
+
33
+ static #formatter(options, params, payload) {
34
+ const status = payload.status.padEnd(12);
35
+ const middle = `${payload.resource} (${payload.id})`.padEnd(40);
36
+
37
+ let prefix = chalk.cyan(payload.prefix ?? '⧗');
38
+ let start = chalk.cyan(status);
39
+ let end = chalk.yellow(payload.end);
40
+
41
+ if (status.toLowerCase().trim() === 'pushed') {
42
+ start = chalk.greenBright.bold(status);
43
+ prefix = chalk.greenBright.bold('✓');
44
+ end = '';
45
+ } else if (status.toLowerCase().trim() === 'deploying') {
46
+ start = chalk.cyanBright.bold(status);
47
+ } else if (status.toLowerCase().trim() === 'deployed') {
48
+ start = chalk.green.bold(status);
49
+ prefix = chalk.green.bold('✓');
50
+ } else if (status.toLowerCase().trim() === 'error') {
51
+ start = chalk.red.bold(status);
52
+ prefix = chalk.red.bold('✗');
53
+ end = chalk.red(payload.errorMessage);
54
+ }
55
+
56
+ return Spinner.#line(prefix, start, middle, end);
57
+ }
58
+
59
+ static #line(prefix, start, middle, end, separator = '•') {
60
+ return `${prefix} ${start} ${separator} ${middle} ${!end ? '' : separator} ${end}`;
61
+
62
+ }
63
+
64
+ constructor(payload, total = 100, startValue = 0) {
65
+ this.bar = Spinner.updatesBar.create(total, startValue, payload)
66
+ }
67
+
68
+ update(payload) {
69
+ this.bar.update(payload);
70
+ return this;
71
+ }
72
+
73
+ fail(payload) {
74
+ this.stopSpinner();
75
+ this.update({ status: 'Error', ...payload });
76
+ }
77
+
78
+ startSpinner(name) {
79
+ let spinnerFrame = 1;
80
+ const spinner = spinners[name] ?? spinners['dots'];
81
+
82
+ this.spinnerInterval = setInterval(() => {
83
+ if (spinnerFrame === spinner.frames.length) spinnerFrame = 1;
84
+ this.bar.update({ prefix: spinner.frames[spinnerFrame++] });
85
+ }, spinner.interval);
86
+ }
87
+
88
+ stopSpinner() {
89
+ clearInterval(this.spinnerInterval);
90
+ }
91
+
92
+ replaceSpinner(name) {
93
+ this.stopSpinner();
94
+ this.startSpinner(name);
95
+ }
96
+ }
97
+
98
+
99
+ module.exports = {
100
+ Spinner,
101
+ SPINNER_ARC,
102
+ SPINNER_DOTS
103
+ }
package/lib/utils.js CHANGED
@@ -1,9 +1,13 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
+ const net = require("net");
4
+ const childProcess = require('child_process');
5
+ const { localConfig, globalConfig } = require("./config");
6
+ const { success } = require('./parser')
3
7
 
4
8
  function getAllFiles(folder) {
5
9
  const files = [];
6
- for(const pathDir of fs.readdirSync(folder)) {
10
+ for (const pathDir of fs.readdirSync(folder)) {
7
11
  const pathAbsolute = path.join(folder, pathDir);
8
12
  if (fs.statSync(pathAbsolute).isDirectory()) {
9
13
  files.push(...getAllFiles(pathAbsolute));
@@ -14,6 +18,247 @@ function getAllFiles(folder) {
14
18
  return files;
15
19
  }
16
20
 
21
+ async function isPortTaken(port) {
22
+ const taken = await new Promise((res, rej) => {
23
+ const tester = net.createServer()
24
+ .once('error', function (err) {
25
+ if (err.code != 'EADDRINUSE') return rej(err)
26
+ res(true)
27
+ })
28
+ .once('listening', function() {
29
+ tester.once('close', function() { res(false) })
30
+ .close()
31
+ })
32
+ .listen(port);
33
+ });
34
+
35
+ return taken;
36
+ }
37
+
38
+ function systemHasCommand(command) {
39
+ const isUsingWindows = process.platform == 'win32'
40
+
41
+ try {
42
+ if(isUsingWindows) {
43
+ childProcess.execSync('where ' + command, { stdio: 'pipe' })
44
+ } else {
45
+ childProcess.execSync(`[[ $(${command} --version) ]] || { exit 1; } && echo "OK"`, { stdio: 'pipe', shell: '/bin/bash' });
46
+ }
47
+ } catch (error) {
48
+ console.log(error);
49
+ return false;
50
+ }
51
+
52
+ return true;
53
+ }
54
+
55
+ const checkDeployConditions = (localConfig) => {
56
+ if (Object.keys(localConfig.data).length === 0) {
57
+ throw new Error("No appwrite.json file found in the current directory. Please run this command again in the folder containing your appwrite.json file, or run 'appwrite init project' to link current directory to an Appwrite project.");
58
+ }
59
+ }
60
+
61
+ function showConsoleLink(serviceName, action, ...ids) {
62
+ const projectId = localConfig.getProject().projectId;
63
+
64
+ const url = new URL(globalConfig.getEndpoint().replace('/v1', '/console'));
65
+ url.pathname += `/project-${projectId}`;
66
+ action = action.toLowerCase();
67
+
68
+ switch (serviceName) {
69
+ case "account":
70
+ url.pathname = url.pathname.replace(`/project-${projectId}`, '');
71
+ url.pathname += getAccountPath(action);
72
+ break;
73
+ case "databases":
74
+ url.pathname += getDatabasePath(action, ids);
75
+ break;
76
+ case "functions":
77
+ url.pathname += getFunctionsPath(action, ids);
78
+ break;
79
+ case "messaging":
80
+ url.pathname += getMessagingPath(action, ids);
81
+ break;
82
+ case "projects":
83
+ url.pathname = url.pathname.replace(`/project-${projectId}`, '');
84
+ url.pathname += getProjectsPath(action, ids);
85
+ break;
86
+ case "storage":
87
+ url.pathname += getBucketsPath(action, ids);
88
+ break;
89
+ case "teams":
90
+ url.pathname += getTeamsPath(action, ids);
91
+ break;
92
+ case "users":
93
+ url.pathname += getUsersPath(action, ids);
94
+ break;
95
+ default:
96
+ return;
97
+ }
98
+
99
+
100
+ success(url);
101
+ }
102
+
103
+ function getAccountPath(action) {
104
+ let path = '/account';
105
+
106
+ if (action === 'listsessions') {
107
+ path += '/sessions';
108
+ }
109
+
110
+ return path;
111
+ }
112
+
113
+ function getDatabasePath(action, ids) {
114
+ let path = '/databases';
115
+
116
+
117
+ if (['get', 'listcollections', 'getcollection', 'listattributes', 'listdocuments', 'getdocument', 'listindexes', 'getdatabaseusage'].includes(action)) {
118
+ path += `/database-${ids[0]}`;
119
+ }
120
+
121
+ if (action === 'getdatabaseusage') {
122
+ path += `/usage`;
123
+ }
124
+
125
+ if (['getcollection', 'listattributes', 'listdocuments', 'getdocument', 'listindexes'].includes(action)) {
126
+ path += `/collection-${ids[1]}`;
127
+ }
128
+
129
+ if (action === 'listattributes') {
130
+ path += '/attributes';
131
+ }
132
+ if (action === 'listindexes') {
133
+ path += '/indexes';
134
+ }
135
+ if (action === 'getdocument') {
136
+ path += `/document-${ids[2]}`;
137
+ }
138
+
139
+
140
+ return path;
141
+ }
142
+
143
+ function getFunctionsPath(action, ids) {
144
+ let path = '/functions';
145
+
146
+ if (action !== 'list') {
147
+ path += `/function-${ids[0]}`;
148
+ }
149
+
150
+ if (action === 'getdeployment') {
151
+ path += `/deployment-${ids[1]}`
152
+ }
153
+
154
+ if (action === 'getexecution' || action === 'listexecution') {
155
+ path += `/executions`
156
+ }
157
+ if (action === 'getfunctionusage') {
158
+ path += `/usage`
159
+ }
160
+
161
+ return path;
162
+ }
163
+
164
+ function getMessagingPath(action, ids) {
165
+ let path = '/messaging';
166
+
167
+ if (['getmessage', 'listmessagelogs'].includes(action)) {
168
+ path += `/message-${ids[0]}`;
169
+ }
170
+
171
+ if (['listproviders', 'getprovider'].includes(action)) {
172
+ path += `/providers`;
173
+ }
174
+
175
+ if (action === 'getprovider') {
176
+ path += `/provider-${ids[0]}`;
177
+ }
178
+
179
+ if (['listtopics', 'gettopic'].includes(action)) {
180
+ path += `/topics`;
181
+ }
182
+
183
+ if (action === 'gettopic') {
184
+ path += `/topic-${ids[0]}`;
185
+ }
186
+
187
+ return path;
188
+ }
189
+
190
+ function getProjectsPath(action, ids) {
191
+ let path = '';
192
+
193
+ if (action !== 'list') {
194
+ path += `/project-${ids[0]}`;
195
+ }
196
+
197
+ if (['listkeys', 'getkey'].includes(action)) {
198
+ path += '/overview/keys'
199
+ }
200
+
201
+ if (['listplatforms', 'getplatform'].includes(action)) {
202
+ path += '/overview/platforms'
203
+ }
204
+
205
+ if (['listwebhooks', 'getwebhook'].includes(action)) {
206
+ path += '/settings/webhooks'
207
+ }
208
+
209
+ if (['getplatform', 'getkey', 'getwebhook'].includes(action)) {
210
+ path += `/${ids[1]}`;
211
+ }
212
+
213
+ return path;
214
+ }
215
+
216
+ function getBucketsPath(action, ids) {
217
+ let path = '/storage';
218
+
219
+ if (action !== 'listbuckets') {
220
+ path += `/bucket-${ids[0]}`;
221
+ }
222
+
223
+ if (action === 'getbucketusage') {
224
+ path += `/usage`
225
+ }
226
+
227
+ if (action === 'getfile') {
228
+ path += `/file-${ids[1]}`
229
+ }
230
+
231
+ return path;
232
+ }
233
+
234
+ function getTeamsPath(action, ids) {
235
+ let path = '/auth/teams';
236
+
237
+ if (action !== 'list') {
238
+ path += `/team-${ids[0]}`;
239
+ }
240
+
241
+ return path;
242
+ }
243
+
244
+ function getUsersPath(action, ids) {
245
+ let path = '/auth';
246
+
247
+ if (action !== 'list') {
248
+ path += `/user-${ids[0]}`;
249
+ }
250
+
251
+ if (action === 'listsessions') {
252
+ path += 'sessions';
253
+ }
254
+
255
+ return path;
256
+ }
257
+
17
258
  module.exports = {
18
- getAllFiles
19
- };
259
+ getAllFiles,
260
+ isPortTaken,
261
+ systemHasCommand,
262
+ checkDeployConditions,
263
+ showConsoleLink
264
+ };
@@ -0,0 +1,17 @@
1
+ const validateRequired = (resource, value) => {
2
+ if (Array.isArray(value)) {
3
+ if (value.length <= 0) {
4
+ return `Please select at least one ${resource}`;
5
+ }
6
+ } else {
7
+ if (value === undefined || value === null || value === 0 || (typeof value === "string" && value.trim() === '')) {
8
+ return `${resource} is required`;
9
+ }
10
+ }
11
+
12
+ return true;
13
+ }
14
+
15
+ module.exports = {
16
+ validateRequired
17
+ }
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.3",
5
+ "version": "6.0.0-rc.1",
6
6
  "license": "BSD-3-Clause",
7
7
  "main": "index.js",
8
8
  "bin": {
@@ -24,13 +24,17 @@
24
24
  "dependencies": {
25
25
  "undici": "^5.28.2",
26
26
  "chalk": "4.1.2",
27
+ "cli-progress": "^3.12.0",
27
28
  "cli-table3": "^0.6.2",
28
29
  "commander": "^9.2.0",
29
30
  "form-data": "^4.0.0",
30
31
  "json-bigint": "^1.0.0",
31
32
  "inquirer": "^8.2.4",
33
+ "inquirer-search-list": "^1.2.6",
32
34
  "tar": "^6.1.11",
33
- "ignore": "^5.2.0"
35
+ "ignore": "^5.2.0",
36
+ "chokidar": "^3.6.0",
37
+ "tail": "^2.2.6"
34
38
  },
35
39
  "devDependencies": {
36
40
  "pkg": "5.8.1"
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
3
- "version": "5.0.3",
3
+ "version": "6.0.0-rc.1",
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.3/appwrite-cli-win-x64.exe",
9
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.1/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.3/appwrite-cli-win-arm64.exe",
18
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.1/appwrite-cli-win-arm64.exe",
19
19
  "bin": [
20
20
  [
21
21
  "appwrite-cli-win-arm64.exe",