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.
- package/README.md +4 -4
- package/docs/examples/functions/create-build.md +1 -1
- package/docs/examples/functions/create-execution.md +1 -0
- package/docs/examples/functions/create.md +1 -0
- package/docs/examples/functions/delete-execution.md +3 -0
- package/docs/examples/functions/update-deployment-build.md +3 -0
- package/docs/examples/functions/update.md +1 -0
- package/docs/examples/projects/create-j-w-t.md +4 -0
- package/docs/examples/projects/update-mock-numbers.md +3 -0
- package/docs/examples/projects/update-session-alerts.md +3 -0
- package/docs/examples/users/create-j-w-t.md +4 -0
- package/docs/examples/vcs/get-repository-contents.md +4 -0
- package/index.js +34 -7
- package/install.ps1 +3 -3
- package/install.sh +2 -2
- package/lib/client.js +17 -3
- package/lib/commands/account.js +306 -152
- package/lib/commands/assistant.js +8 -5
- package/lib/commands/avatars.js +114 -58
- package/lib/commands/console.js +8 -5
- package/lib/commands/databases.js +353 -164
- package/lib/commands/functions.js +310 -100
- package/lib/commands/generic.js +206 -54
- package/lib/commands/graphql.js +14 -8
- package/lib/commands/health.js +140 -71
- package/lib/commands/init.js +250 -155
- package/lib/commands/locale.js +50 -26
- package/lib/commands/messaging.js +334 -156
- package/lib/commands/migrations.js +98 -50
- package/lib/commands/project.js +38 -20
- package/lib/commands/projects.js +449 -144
- package/lib/commands/proxy.js +32 -17
- package/lib/commands/pull.js +231 -0
- package/lib/commands/push.js +1518 -0
- package/lib/commands/run.js +282 -0
- package/lib/commands/storage.js +160 -76
- package/lib/commands/teams.js +102 -50
- package/lib/commands/users.js +324 -134
- package/lib/commands/vcs.js +102 -29
- package/lib/config.js +190 -18
- package/lib/emulation/docker.js +187 -0
- package/lib/emulation/utils.js +177 -0
- package/lib/id.js +30 -0
- package/lib/paginate.js +1 -2
- package/lib/parser.js +69 -12
- package/lib/questions.js +452 -80
- package/lib/sdks.js +1 -1
- package/lib/spinner.js +103 -0
- package/lib/utils.js +242 -4
- package/lib/validations.js +17 -0
- package/package.json +6 -2
- package/scoop/appwrite.json +3 -3
- package/lib/commands/deploy.js +0 -940
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const childProcess = require('child_process');
|
|
2
|
+
const { localConfig } = require("../config");
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const { log,success } = require("../parser");
|
|
6
|
+
const { openRuntimesVersion, systemTools } = require("./utils");
|
|
7
|
+
const ID = require("../id");
|
|
8
|
+
|
|
9
|
+
const activeDockerIds = {};
|
|
10
|
+
|
|
11
|
+
async function dockerStop(id) {
|
|
12
|
+
delete activeDockerIds[id];
|
|
13
|
+
const stopProcess = childProcess.spawn('docker', ['rm', '--force', id], {
|
|
14
|
+
stdio: 'pipe',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
await new Promise((res) => { stopProcess.on('close', res) });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function dockerPull(func) {
|
|
21
|
+
log('Pulling Docker image of function runtime ...');
|
|
22
|
+
|
|
23
|
+
const runtimeChunks = func.runtime.split("-");
|
|
24
|
+
const runtimeVersion = runtimeChunks.pop();
|
|
25
|
+
const runtimeName = runtimeChunks.join("-");
|
|
26
|
+
const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
|
|
27
|
+
|
|
28
|
+
const pullProcess = childProcess.spawn('docker', ['pull', imageName], {
|
|
29
|
+
stdio: 'pipe',
|
|
30
|
+
pwd: path.join(process.cwd(), func.path)
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
pullProcess.stderr.on('data', (data) => {
|
|
34
|
+
process.stderr.write(`\n${data}$ `);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
await new Promise((res) => { pullProcess.on('close', res) });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function dockerBuild(func, variables) {
|
|
41
|
+
log('Building function using Docker ...');
|
|
42
|
+
|
|
43
|
+
const runtimeChunks = func.runtime.split("-");
|
|
44
|
+
const runtimeVersion = runtimeChunks.pop();
|
|
45
|
+
const runtimeName = runtimeChunks.join("-");
|
|
46
|
+
const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
|
|
47
|
+
|
|
48
|
+
const functionDir = path.join(process.cwd(), func.path);
|
|
49
|
+
|
|
50
|
+
const id = ID.unique();
|
|
51
|
+
|
|
52
|
+
const params = [ 'run' ];
|
|
53
|
+
params.push('--name', id);
|
|
54
|
+
params.push('-v', `${functionDir}/:/mnt/code:rw`);
|
|
55
|
+
params.push('-e', 'APPWRITE_ENV=development');
|
|
56
|
+
params.push('-e', 'OPEN_RUNTIMES_ENV=development');
|
|
57
|
+
params.push('-e', 'OPEN_RUNTIMES_SECRET=');
|
|
58
|
+
params.push('-e', `OPEN_RUNTIMES_ENTRYPOINT=${func.entrypoint}`);
|
|
59
|
+
|
|
60
|
+
for(const k of Object.keys(variables)) {
|
|
61
|
+
params.push('-e', `${k}=${variables[k]}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
params.push(imageName, 'sh', '-c', `helpers/build.sh "${func.commands}"`);
|
|
65
|
+
|
|
66
|
+
const buildProcess = childProcess.spawn('docker', params, {
|
|
67
|
+
stdio: 'pipe',
|
|
68
|
+
pwd: functionDir
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
buildProcess.stdout.on('data', (data) => {
|
|
72
|
+
process.stdout.write(`\n${data}`);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
buildProcess.stderr.on('data', (data) => {
|
|
76
|
+
process.stderr.write(`\n${data}`);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await new Promise((res) => { buildProcess.on('close', res) });
|
|
80
|
+
|
|
81
|
+
const copyPath = path.join(process.cwd(), func.path, '.appwrite', 'build.tar.gz');
|
|
82
|
+
const copyDir = path.dirname(copyPath);
|
|
83
|
+
if (!fs.existsSync(copyDir)) {
|
|
84
|
+
fs.mkdirSync(copyDir, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const copyProcess = childProcess.spawn('docker', ['cp', `${id}:/mnt/code/code.tar.gz`, copyPath], {
|
|
88
|
+
stdio: 'pipe',
|
|
89
|
+
pwd: functionDir
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
await new Promise((res) => { copyProcess.on('close', res) });
|
|
93
|
+
|
|
94
|
+
const cleanupProcess = childProcess.spawn('docker', ['rm', '--force', id], {
|
|
95
|
+
stdio: 'pipe',
|
|
96
|
+
pwd: functionDir
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
await new Promise((res) => { cleanupProcess.on('close', res) });
|
|
100
|
+
|
|
101
|
+
delete activeDockerIds[id];
|
|
102
|
+
|
|
103
|
+
const tempPath = path.join(process.cwd(), func.path, 'code.tar.gz');
|
|
104
|
+
if (fs.existsSync(tempPath)) {
|
|
105
|
+
fs.rmSync(tempPath, { force: true });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function dockerStart(func, variables, port) {
|
|
110
|
+
log('Starting function using Docker ...');
|
|
111
|
+
|
|
112
|
+
log("Permissions, events, CRON and timeouts dont apply when running locally.");
|
|
113
|
+
|
|
114
|
+
log('💡 Hint: Function automatically restarts when you edit your code.');
|
|
115
|
+
|
|
116
|
+
success(`Visit http://localhost:${port}/ to execute your function.`);
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
const runtimeChunks = func.runtime.split("-");
|
|
120
|
+
const runtimeVersion = runtimeChunks.pop();
|
|
121
|
+
const runtimeName = runtimeChunks.join("-");
|
|
122
|
+
const imageName = `openruntimes/${runtimeName}:${openRuntimesVersion}-${runtimeVersion}`;
|
|
123
|
+
|
|
124
|
+
const tool = systemTools[runtimeName];
|
|
125
|
+
|
|
126
|
+
const functionDir = path.join(process.cwd(), func.path);
|
|
127
|
+
|
|
128
|
+
const id = ID.unique();
|
|
129
|
+
|
|
130
|
+
const params = [ 'run' ];
|
|
131
|
+
params.push('--rm');
|
|
132
|
+
params.push('-d');
|
|
133
|
+
params.push('--name', id);
|
|
134
|
+
params.push('-p', `${port}:3000`);
|
|
135
|
+
params.push('-e', 'APPWRITE_ENV=development');
|
|
136
|
+
params.push('-e', 'OPEN_RUNTIMES_ENV=development');
|
|
137
|
+
params.push('-e', 'OPEN_RUNTIMES_SECRET=');
|
|
138
|
+
|
|
139
|
+
for(const k of Object.keys(variables)) {
|
|
140
|
+
params.push('-e', `${k}=${variables[k]}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
params.push('-v', `${functionDir}/.appwrite/logs.txt:/mnt/logs/dev_logs.log:rw`);
|
|
144
|
+
params.push('-v', `${functionDir}/.appwrite/errors.txt:/mnt/logs/dev_errors.log:rw`);
|
|
145
|
+
params.push('-v', `${functionDir}/.appwrite/build.tar.gz:/mnt/code/code.tar.gz:ro`);
|
|
146
|
+
params.push(imageName, 'sh', '-c', `helpers/start.sh "${tool.startCommand}"`);
|
|
147
|
+
|
|
148
|
+
childProcess.spawn('docker', params, {
|
|
149
|
+
stdio: 'pipe',
|
|
150
|
+
pwd: functionDir
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
activeDockerIds[id] = true;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function dockerCleanup() {
|
|
157
|
+
await dockerStop();
|
|
158
|
+
|
|
159
|
+
const functions = localConfig.getFunctions();
|
|
160
|
+
for(const func of functions) {
|
|
161
|
+
const appwritePath = path.join(process.cwd(), func.path, '.appwrite');
|
|
162
|
+
if (fs.existsSync(appwritePath)) {
|
|
163
|
+
fs.rmSync(appwritePath, { recursive: true, force: true });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const tempPath = path.join(process.cwd(), func.path, 'code.tar.gz');
|
|
167
|
+
if (fs.existsSync(tempPath)) {
|
|
168
|
+
fs.rmSync(tempPath, { force: true });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function dockerStopActive() {
|
|
174
|
+
const ids = Object.keys(activeDockerIds);
|
|
175
|
+
for await (const id of ids) {
|
|
176
|
+
await dockerStop(id);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
module.exports = {
|
|
181
|
+
dockerStop,
|
|
182
|
+
dockerPull,
|
|
183
|
+
dockerBuild,
|
|
184
|
+
dockerStart,
|
|
185
|
+
dockerCleanup,
|
|
186
|
+
dockerStopActive,
|
|
187
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
const EventEmitter = require('node:events');
|
|
2
|
+
const { projectsCreateJWT } = require('../commands/projects');
|
|
3
|
+
const { localConfig } = require("../config");
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const openRuntimesVersion = 'v3';
|
|
7
|
+
|
|
8
|
+
const runtimeNames = {
|
|
9
|
+
'node': 'Node.js',
|
|
10
|
+
'php': 'PHP',
|
|
11
|
+
'ruby': 'Ruby',
|
|
12
|
+
'python': 'Python',
|
|
13
|
+
'python-ml': 'Python (ML)',
|
|
14
|
+
'deno': 'Deno',
|
|
15
|
+
'dart': 'Dart',
|
|
16
|
+
'dotnet': '.NET',
|
|
17
|
+
'java': 'Java',
|
|
18
|
+
'swift': 'Swift',
|
|
19
|
+
'kotlin': 'Kotlin',
|
|
20
|
+
'bun': 'Bun'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const systemTools = {
|
|
24
|
+
'node': {
|
|
25
|
+
isCompiled: false,
|
|
26
|
+
startCommand: "node src/server.js",
|
|
27
|
+
dependencyFiles: [ "package.json", "package-lock.json" ]
|
|
28
|
+
},
|
|
29
|
+
'php': {
|
|
30
|
+
isCompiled: false,
|
|
31
|
+
startCommand: "php src/server.php",
|
|
32
|
+
dependencyFiles: [ "composer.json", "composer.lock" ]
|
|
33
|
+
},
|
|
34
|
+
'ruby': {
|
|
35
|
+
isCompiled: false,
|
|
36
|
+
startCommand: "bundle exec puma -b tcp://0.0.0.0:3000 -e production",
|
|
37
|
+
dependencyFiles: [ "Gemfile", "Gemfile.lock" ]
|
|
38
|
+
},
|
|
39
|
+
'python': {
|
|
40
|
+
isCompiled: false,
|
|
41
|
+
startCommand: "python3 src/server.py",
|
|
42
|
+
dependencyFiles: [ "requirements.txt", "requirements.lock" ]
|
|
43
|
+
},
|
|
44
|
+
'python-ml': {
|
|
45
|
+
isCompiled: false,
|
|
46
|
+
startCommand: "python3 src/server.py",
|
|
47
|
+
dependencyFiles: [ "requirements.txt", "requirements.lock" ]
|
|
48
|
+
},
|
|
49
|
+
'deno': {
|
|
50
|
+
isCompiled: false,
|
|
51
|
+
startCommand: "deno start",
|
|
52
|
+
dependencyFiles: [ ]
|
|
53
|
+
},
|
|
54
|
+
'dart': {
|
|
55
|
+
isCompiled: true,
|
|
56
|
+
startCommand: "src/function/server",
|
|
57
|
+
dependencyFiles: [ ]
|
|
58
|
+
},
|
|
59
|
+
'dotnet': {
|
|
60
|
+
isCompiled: true,
|
|
61
|
+
startCommand: "dotnet src/function/DotNetRuntime.dll",
|
|
62
|
+
dependencyFiles: [ ]
|
|
63
|
+
},
|
|
64
|
+
'java': {
|
|
65
|
+
isCompiled: true,
|
|
66
|
+
startCommand: "java -jar src/function/java-runtime-1.0.0.jar",
|
|
67
|
+
dependencyFiles: [ ]
|
|
68
|
+
},
|
|
69
|
+
'swift': {
|
|
70
|
+
isCompiled: true,
|
|
71
|
+
startCommand: "src/function/Runtime serve --env production --hostname 0.0.0.0 --port 3000",
|
|
72
|
+
dependencyFiles: [ ]
|
|
73
|
+
},
|
|
74
|
+
'kotlin': {
|
|
75
|
+
isCompiled: true,
|
|
76
|
+
startCommand: "java -jar src/function/kotlin-runtime-1.0.0.jar",
|
|
77
|
+
dependencyFiles: [ ]
|
|
78
|
+
},
|
|
79
|
+
'bun': {
|
|
80
|
+
isCompiled: false,
|
|
81
|
+
startCommand: "bun src/server.ts",
|
|
82
|
+
dependencyFiles: [ "package.json", "package-lock.json", "bun.lockb" ]
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const JwtManager = {
|
|
87
|
+
userJwt: null,
|
|
88
|
+
functionJwt: null,
|
|
89
|
+
|
|
90
|
+
timerWarn: null,
|
|
91
|
+
timerError: null,
|
|
92
|
+
|
|
93
|
+
async setup(userId = null) {
|
|
94
|
+
if(this.timerWarn) {
|
|
95
|
+
clearTimeout(this.timerWarn);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if(this.timerError) {
|
|
99
|
+
clearTimeout(this.timerError);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this.timerWarn = setTimeout(() => {
|
|
103
|
+
log("Warning: Authorized JWT will expire in 5 minutes. Please stop and re-run the command to refresh tokens for 1 hour.");
|
|
104
|
+
}, 1000 * 60 * 55); // 55 mins
|
|
105
|
+
|
|
106
|
+
this.timerError = setTimeout(() => {
|
|
107
|
+
log("Warning: Authorized JWT just expired. Please stop and re-run the command to obtain new tokens with 1 hour validity.");
|
|
108
|
+
log("Some Appwrite API communication is not authorized now.")
|
|
109
|
+
}, 1000 * 60 * 60); // 60 mins
|
|
110
|
+
|
|
111
|
+
if(userId) {
|
|
112
|
+
await usersGet({
|
|
113
|
+
userId,
|
|
114
|
+
parseOutput: false
|
|
115
|
+
});
|
|
116
|
+
const userResponse = await usersCreateJWT({
|
|
117
|
+
userId,
|
|
118
|
+
duration: 60*60,
|
|
119
|
+
parseOutput: false
|
|
120
|
+
});
|
|
121
|
+
this.userJwt = userResponse.jwt;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const functionResponse = await projectsCreateJWT({
|
|
125
|
+
projectId: localConfig.getProject().projectId,
|
|
126
|
+
// TODO: Once we have endpoint for this, use it
|
|
127
|
+
scopes: ["sessions.write","users.read","users.write","teams.read","teams.write","databases.read","databases.write","collections.read","collections.write","attributes.read","attributes.write","indexes.read","indexes.write","documents.read","documents.write","files.read","files.write","buckets.read","buckets.write","functions.read","functions.write","execution.read","execution.write","locale.read","avatars.read","health.read","providers.read","providers.write","messages.read","messages.write","topics.read","topics.write","subscribers.read","subscribers.write","targets.read","targets.write","rules.read","rules.write","migrations.read","migrations.write","vcs.read","vcs.write","assistant.read"],
|
|
128
|
+
duration: 60*60,
|
|
129
|
+
parseOutput: false
|
|
130
|
+
});
|
|
131
|
+
this.functionJwt = functionResponse.jwt;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const Queue = {
|
|
136
|
+
files: [],
|
|
137
|
+
locked: false,
|
|
138
|
+
events: new EventEmitter(),
|
|
139
|
+
debounce: null,
|
|
140
|
+
push(file) {
|
|
141
|
+
if(!this.files.includes(file)) {
|
|
142
|
+
this.files.push(file);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if(!this.locked) {
|
|
146
|
+
this._trigger();
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
lock() {
|
|
150
|
+
this.files = [];
|
|
151
|
+
this.locked = true;
|
|
152
|
+
},
|
|
153
|
+
unlock() {
|
|
154
|
+
this.locked = false;
|
|
155
|
+
if(this.files.length > 0) {
|
|
156
|
+
this._trigger();
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
_trigger() {
|
|
160
|
+
if(this.debounce) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.debounce = setTimeout(() => {
|
|
165
|
+
this.events.emit('reload', { files: this.files });
|
|
166
|
+
this.debounce = null;
|
|
167
|
+
}, 300);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
module.exports = {
|
|
172
|
+
openRuntimesVersion,
|
|
173
|
+
runtimeNames,
|
|
174
|
+
systemTools,
|
|
175
|
+
JwtManager,
|
|
176
|
+
Queue
|
|
177
|
+
}
|
package/lib/id.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class ID {
|
|
2
|
+
// Generate an hex ID based on timestamp
|
|
3
|
+
// Recreated from https://www.php.net/manual/en/function.uniqid.php
|
|
4
|
+
static #hexTimestamp() {
|
|
5
|
+
const now = new Date();
|
|
6
|
+
const sec = Math.floor(now.getTime() / 1000);
|
|
7
|
+
const msec = now.getMilliseconds();
|
|
8
|
+
|
|
9
|
+
// Convert to hexadecimal
|
|
10
|
+
const hexTimestamp = sec.toString(16) + msec.toString(16).padStart(5, '0');
|
|
11
|
+
return hexTimestamp;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static custom(id) {
|
|
15
|
+
return id
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static unique(padding = 7) {
|
|
19
|
+
// Generate a unique ID with padding to have a longer ID
|
|
20
|
+
const baseId = ID.#hexTimestamp();
|
|
21
|
+
let randomPadding = '';
|
|
22
|
+
for (let i = 0; i < padding; i++) {
|
|
23
|
+
const randomHexDigit = Math.floor(Math.random() * 16).toString(16);
|
|
24
|
+
randomPadding += randomHexDigit;
|
|
25
|
+
}
|
|
26
|
+
return baseId + randomPadding;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = ID;
|
package/lib/paginate.js
CHANGED
|
@@ -5,7 +5,6 @@ const paginate = async (action, args = {}, limit = 100, wrapper = '') => {
|
|
|
5
5
|
|
|
6
6
|
while (true) {
|
|
7
7
|
const offset = pageNumber * limit;
|
|
8
|
-
|
|
9
8
|
// Merge the limit and offset into the args
|
|
10
9
|
const response = await action({
|
|
11
10
|
...args,
|
|
@@ -48,4 +47,4 @@ const paginate = async (action, args = {}, limit = 100, wrapper = '') => {
|
|
|
48
47
|
|
|
49
48
|
module.exports = {
|
|
50
49
|
paginate
|
|
51
|
-
};
|
|
50
|
+
};
|
package/lib/parser.js
CHANGED
|
@@ -2,10 +2,18 @@ const chalk = require('chalk');
|
|
|
2
2
|
const commander = require('commander');
|
|
3
3
|
const Table = require('cli-table3');
|
|
4
4
|
const { description } = require('../package.json');
|
|
5
|
+
const { globalConfig } = require("./config.js");
|
|
6
|
+
const os = require('os');
|
|
7
|
+
const Client = require("./client");
|
|
5
8
|
|
|
6
9
|
const cliConfig = {
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
verbose: false,
|
|
11
|
+
json: false,
|
|
12
|
+
force: false,
|
|
13
|
+
all: false,
|
|
14
|
+
ids: [],
|
|
15
|
+
report: false,
|
|
16
|
+
reportData: {}
|
|
9
17
|
};
|
|
10
18
|
|
|
11
19
|
const parse = (data) => {
|
|
@@ -110,17 +118,60 @@ const drawJSON = (data) => {
|
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
const parseError = (err) => {
|
|
113
|
-
if(cliConfig.
|
|
114
|
-
|
|
115
|
-
|
|
121
|
+
if (cliConfig.report) {
|
|
122
|
+
(async () => {
|
|
123
|
+
let appwriteVersion = 'unknown';
|
|
124
|
+
const endpoint = globalConfig.getEndpoint();
|
|
125
|
+
const isCloud = endpoint.includes('cloud.appwrite.io') ? 'Yes' : 'No';
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
const client = new Client().setEndpoint(endpoint);
|
|
129
|
+
const res = await client.call('get', '/health/version');
|
|
130
|
+
appwriteVersion = res.version;
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const version = '6.0.0-rc.1';
|
|
135
|
+
const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
|
|
136
|
+
const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud}`;
|
|
137
|
+
|
|
138
|
+
const stack = '```\n' + err.stack + '\n```';
|
|
139
|
+
|
|
140
|
+
const githubIssueUrl = new URL('https://github.com/appwrite/appwrite/issues/new');
|
|
141
|
+
githubIssueUrl.searchParams.append('labels', 'bug');
|
|
142
|
+
githubIssueUrl.searchParams.append('template', 'bug.yaml');
|
|
143
|
+
githubIssueUrl.searchParams.append('title', `🐛 Bug Report: ${err.message}`);
|
|
144
|
+
githubIssueUrl.searchParams.append('actual-behavior', `CLI Error:\n${stack}`);
|
|
145
|
+
githubIssueUrl.searchParams.append('steps-to-reproduce', stepsToReproduce);
|
|
146
|
+
githubIssueUrl.searchParams.append('environment', yourEnvironment);
|
|
147
|
+
|
|
148
|
+
log(`To report this error you can:\n - Create a support ticket in our Discord server https://appwrite.io/discord \n - Create an issue in our Github\n ${githubIssueUrl.href}\n`);
|
|
116
149
|
|
|
117
|
-
error(err.message);
|
|
118
150
|
|
|
119
|
-
|
|
151
|
+
error('\n Stack Trace: \n');
|
|
152
|
+
console.error(err);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
})()
|
|
155
|
+
} else {
|
|
156
|
+
if (cliConfig.verbose) {
|
|
157
|
+
console.error(err);
|
|
158
|
+
} else {
|
|
159
|
+
log('For detailed error pass the --verbose or --report flag');
|
|
160
|
+
error(err.message);
|
|
161
|
+
}
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
|
|
120
165
|
}
|
|
121
166
|
|
|
122
167
|
const actionRunner = (fn) => {
|
|
123
|
-
return (...args) =>
|
|
168
|
+
return (...args) => {
|
|
169
|
+
if (cliConfig.all && (Array.isArray(cliConfig.ids) && cliConfig.ids.length !== 0)) {
|
|
170
|
+
error(`The '--all' and '--id' flags cannot be used together.`);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
return fn(...args).catch(parseError)
|
|
174
|
+
};
|
|
124
175
|
}
|
|
125
176
|
|
|
126
177
|
const parseInteger = (value) => {
|
|
@@ -156,10 +207,12 @@ const commandDescriptions = {
|
|
|
156
207
|
"graphql": `The graphql command allows you to query and mutate any resource type on your Appwrite server.`,
|
|
157
208
|
"avatars": `The avatars command aims to help you complete everyday tasks related to your app image, icons, and avatars.`,
|
|
158
209
|
"databases": `The databases command allows you to create structured collections of documents, query and filter lists of documents.`,
|
|
159
|
-
"
|
|
210
|
+
"init": `The init command provides a convenient wrapper for creating and initializing project, functions, collections, buckets, teams and messaging in Appwrite.`,
|
|
211
|
+
"push": `The push command provides a convenient wrapper for pushing your functions, collections, buckets, teams and messaging.`,
|
|
212
|
+
"run": `The run command allows you to run project locally to allow easy development and quick debugging.`,
|
|
160
213
|
"functions": `The functions command allows you view, create and manage your Cloud Functions.`,
|
|
161
214
|
"health": `The health command allows you to both validate and monitor your Appwrite server's health.`,
|
|
162
|
-
"
|
|
215
|
+
"pull": `The pull command helps you pull your Appwrite project, functions, collections, buckets, teams and messaging`,
|
|
163
216
|
"locale": `The locale command allows you to customize your app based on your users' location.`,
|
|
164
217
|
"projects": `The projects command allows you to view, create and manage your Appwrite projects.`,
|
|
165
218
|
"storage": `The storage command allows you to manage your project files.`,
|
|
@@ -168,6 +221,8 @@ const commandDescriptions = {
|
|
|
168
221
|
"client": `The client command allows you to configure your CLI`,
|
|
169
222
|
"login": `The login command allows you to authenticate and manage a user account.`,
|
|
170
223
|
"logout": `The logout command allows you to logout of your Appwrite account.`,
|
|
224
|
+
"whoami": `The whoami command gives information about the currently logged in user.`,
|
|
225
|
+
"register": `Outputs the link to create an Appwrite account..`,
|
|
171
226
|
"console" : `The console command allows gives you access to the APIs used by the Appwrite console.`,
|
|
172
227
|
"assistant": `The assistant command allows you to interact with the Appwrite Assistant AI`,
|
|
173
228
|
"messaging": `The messaging command allows you to send messages.`,
|
|
@@ -179,6 +234,7 @@ const commandDescriptions = {
|
|
|
179
234
|
}
|
|
180
235
|
|
|
181
236
|
module.exports = {
|
|
237
|
+
drawTable,
|
|
182
238
|
parse,
|
|
183
239
|
actionRunner,
|
|
184
240
|
parseInteger,
|
|
@@ -187,5 +243,6 @@ module.exports = {
|
|
|
187
243
|
success,
|
|
188
244
|
error,
|
|
189
245
|
commandDescriptions,
|
|
190
|
-
cliConfig
|
|
191
|
-
|
|
246
|
+
cliConfig,
|
|
247
|
+
drawTable
|
|
248
|
+
}
|