appwrite-cli 1.1.1 → 2.0.0
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/Formula/appwrite.rb +1 -1
- package/LICENSE.md +2 -2
- package/README.md +4 -4
- package/docs/examples/account/create-phone-session.md +1 -1
- package/docs/examples/account/create.md +1 -1
- package/docs/examples/account/update-password.md +1 -1
- package/docs/examples/account/update-phone.md +1 -1
- package/docs/examples/console/variables.md +1 -0
- package/docs/examples/databases/create-relationship-attribute.md +9 -0
- package/docs/examples/databases/get-document.md +2 -1
- package/docs/examples/databases/update-boolean-attribute.md +6 -0
- package/docs/examples/databases/update-datetime-attribute.md +6 -0
- package/docs/examples/databases/update-email-attribute.md +6 -0
- package/docs/examples/databases/update-enum-attribute.md +7 -0
- package/docs/examples/databases/update-float-attribute.md +8 -0
- package/docs/examples/databases/update-integer-attribute.md +8 -0
- package/docs/examples/databases/update-ip-attribute.md +6 -0
- package/docs/examples/databases/update-relationship-attribute.md +5 -0
- package/docs/examples/databases/update-string-attribute.md +6 -0
- package/docs/examples/databases/update-url-attribute.md +6 -0
- package/docs/examples/functions/{retry-build.md → create-build.md} +1 -1
- package/docs/examples/functions/create.md +1 -1
- package/docs/examples/functions/update.md +1 -1
- package/docs/examples/graphql/mutation.md +2 -0
- package/docs/examples/graphql/query.md +2 -0
- package/docs/examples/projects/create.md +1 -0
- package/docs/examples/projects/update-auth-duration.md +3 -0
- package/docs/examples/projects/update-auth-password-dictionary.md +3 -0
- package/docs/examples/projects/update-auth-password-history.md +3 -0
- package/docs/examples/projects/update-auth-sessions-limit.md +3 -0
- package/docs/examples/projects/update-o-auth2.md +1 -0
- package/docs/examples/teams/create-membership.md +3 -1
- package/docs/examples/teams/get-prefs.md +2 -0
- package/docs/examples/teams/{update.md → update-name.md} +1 -1
- package/docs/examples/teams/update-prefs.md +3 -0
- package/docs/examples/users/update-password.md +1 -1
- package/docs/examples/users/update-phone.md +1 -1
- package/index.js +16 -1
- package/install.ps1 +2 -2
- package/install.sh +1 -1
- package/lib/client.js +7 -7
- package/lib/commands/account.js +46 -11
- package/lib/commands/avatars.js +3 -1
- package/lib/commands/console.js +44 -0
- package/lib/commands/databases.js +735 -109
- package/lib/commands/deploy.js +350 -141
- package/lib/commands/functions.js +44 -16
- package/lib/commands/generic.js +15 -3
- package/lib/commands/graphql.js +85 -0
- package/lib/commands/health.js +3 -1
- package/lib/commands/init.js +224 -162
- package/lib/commands/locale.js +3 -1
- package/lib/commands/projects.js +223 -9
- package/lib/commands/storage.js +43 -13
- package/lib/commands/teams.js +107 -19
- package/lib/commands/users.js +62 -11
- package/lib/config.js +122 -5
- package/lib/parser.js +7 -2
- package/lib/questions.js +311 -257
- package/package.json +1 -1
package/lib/commands/init.js
CHANGED
|
@@ -3,206 +3,268 @@ const path = require("path");
|
|
|
3
3
|
const childProcess = require('child_process');
|
|
4
4
|
const { Command } = require("commander");
|
|
5
5
|
const inquirer = require("inquirer");
|
|
6
|
-
const { teamsCreate } = require("./teams");
|
|
6
|
+
const { teamsCreate, teamsList } = require("./teams");
|
|
7
7
|
const { projectsCreate } = require("./projects");
|
|
8
8
|
const { functionsCreate } = require("./functions");
|
|
9
|
-
const { databasesListCollections, databasesList } = require("./databases");
|
|
9
|
+
const { databasesGet, databasesListCollections, databasesList } = require("./databases");
|
|
10
|
+
const { storageListBuckets } = require("./storage");
|
|
10
11
|
const { sdkForConsole } = require("../sdks");
|
|
11
12
|
const { localConfig } = require("../config");
|
|
12
13
|
const { questionsInitProject, questionsInitFunction, questionsInitCollection } = require("../questions");
|
|
13
14
|
const { success, log, actionRunner, commandDescriptions } = require("../parser");
|
|
14
15
|
|
|
15
16
|
const init = new Command("init")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
.description(commandDescriptions['init'])
|
|
18
|
+
.configureHelp({
|
|
19
|
+
helpWidth: process.stdout.columns || 80
|
|
20
|
+
})
|
|
21
|
+
.action(actionRunner(async (_options, command) => {
|
|
22
|
+
command.help();
|
|
23
|
+
}));
|
|
20
24
|
|
|
21
25
|
const initProject = async () => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
let response = {}
|
|
27
|
+
let answers = await inquirer.prompt(questionsInitProject)
|
|
28
|
+
if (!answers.project) process.exit(1)
|
|
29
|
+
|
|
30
|
+
let sdk = await sdkForConsole();
|
|
31
|
+
if (answers.start == "new") {
|
|
32
|
+
response = await teamsCreate({
|
|
33
|
+
teamId: 'unique()',
|
|
34
|
+
name: answers.project,
|
|
35
|
+
sdk,
|
|
36
|
+
parseOutput: false
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
let teamId = response['$id'];
|
|
40
|
+
response = await projectsCreate({
|
|
41
|
+
projectId: answers.id,
|
|
42
|
+
name: answers.project,
|
|
43
|
+
teamId,
|
|
44
|
+
parseOutput: false
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
localConfig.setProject(response['$id'], response.name);
|
|
48
|
+
} else {
|
|
49
|
+
localConfig.setProject(answers.project.id, answers.project.name);
|
|
50
|
+
}
|
|
51
|
+
success();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const initFunction = async () => {
|
|
55
|
+
// TODO: Add CI/CD support (ID, name, runtime)
|
|
56
|
+
let answers = await inquirer.prompt(questionsInitFunction)
|
|
57
|
+
let functionFolder = path.join(process.cwd(), 'functions');
|
|
58
|
+
|
|
59
|
+
if (!fs.existsSync(functionFolder)) {
|
|
60
|
+
fs.mkdirSync(functionFolder, {
|
|
61
|
+
recursive: true
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const functionDir = path.join(functionFolder, answers.name);
|
|
66
|
+
|
|
67
|
+
if (fs.existsSync(functionDir)) {
|
|
68
|
+
throw new Error(`( ${answers.name} ) already exists in the current directory. Please choose another name.`);
|
|
69
|
+
}
|
|
34
70
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
71
|
+
if (!answers.runtime.entrypoint) {
|
|
72
|
+
log(`Entrypoint for this runtime not found. You will be asked to configure entrypoint when you first deploy the function.`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
let response = await functionsCreate({
|
|
76
|
+
functionId: answers.id,
|
|
77
|
+
name: answers.name,
|
|
78
|
+
runtime: answers.runtime.id,
|
|
79
|
+
parseOutput: false
|
|
41
80
|
})
|
|
42
81
|
|
|
43
|
-
|
|
44
|
-
} else {
|
|
45
|
-
localConfig.setProject(answers.project.id, answers.project.name);
|
|
46
|
-
}
|
|
47
|
-
success();
|
|
48
|
-
}
|
|
82
|
+
fs.mkdirSync(functionDir, "777");
|
|
49
83
|
|
|
50
|
-
|
|
51
|
-
// TODO: Add CI/CD support (ID, name, runtime)
|
|
52
|
-
let answers = await inquirer.prompt(questionsInitFunction)
|
|
53
|
-
let functionFolder = path.join(process.cwd(), 'functions');
|
|
84
|
+
let gitInitCommands = "git clone --depth 1 --sparse https://github.com/appwrite/functions-starter ."; // depth prevents fetching older commits reducing the amount fetched
|
|
54
85
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const functionDir = path.join(functionFolder, answers.name);
|
|
62
|
-
|
|
63
|
-
if (fs.existsSync(functionDir)) {
|
|
64
|
-
throw new Error(`( ${answers.name} ) already exists in the current directory. Please choose another name.`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if(!answers.runtime.entrypoint) {
|
|
68
|
-
log(`Entrypoint for this runtime not found. You will be asked to configure entrypoint when you first deploy the function.`);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let response = await functionsCreate({
|
|
72
|
-
functionId: answers.id,
|
|
73
|
-
name: answers.name,
|
|
74
|
-
runtime: answers.runtime.id,
|
|
75
|
-
parseOutput: false
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
fs.mkdirSync(functionDir, "777");
|
|
79
|
-
|
|
80
|
-
let gitInitCommands = "git clone --depth 1 --sparse https://github.com/appwrite/functions-starter ."; // depth prevents fetching older commits reducing the amount fetched
|
|
81
|
-
|
|
82
|
-
let gitPullCommands = `git sparse-checkout add ${answers.runtime.id}`;
|
|
83
|
-
|
|
84
|
-
/* Force use CMD as powershell does not support && */
|
|
85
|
-
if (process.platform == 'win32') {
|
|
86
|
-
gitInitCommands = 'cmd /c "' + gitInitCommands + '"';
|
|
87
|
-
gitPullCommands = 'cmd /c "' + gitPullCommands + '"';
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/* Execute the child process but do not print any std output */
|
|
91
|
-
try {
|
|
92
|
-
childProcess.execSync(gitInitCommands, { stdio: 'pipe', cwd: functionDir });
|
|
93
|
-
childProcess.execSync(gitPullCommands, { stdio: 'pipe', cwd: functionDir });
|
|
94
|
-
} catch (error) {
|
|
95
|
-
/* Specialised errors with recommended actions to take */
|
|
96
|
-
if (error.message.includes('error: unknown option')) {
|
|
97
|
-
throw new Error(`${error.message} \n\nSuggestion: Try updating your git to the latest version, then trying to run this command again.`)
|
|
98
|
-
} else if (error.message.includes('is not recognized as an internal or external command,') || error.message.includes('command not found')) {
|
|
99
|
-
throw new Error(`${error.message} \n\nSuggestion: It appears that git is not installed, try installing git then trying to run this command again.`)
|
|
100
|
-
} else {
|
|
101
|
-
throw error;
|
|
86
|
+
let gitPullCommands = `git sparse-checkout add ${answers.runtime.id}`;
|
|
87
|
+
|
|
88
|
+
/* Force use CMD as powershell does not support && */
|
|
89
|
+
if (process.platform == 'win32') {
|
|
90
|
+
gitInitCommands = 'cmd /c "' + gitInitCommands + '"';
|
|
91
|
+
gitPullCommands = 'cmd /c "' + gitPullCommands + '"';
|
|
102
92
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
});
|
|
118
|
-
} else {
|
|
119
|
-
fs.copyFileSync(src, dest);
|
|
93
|
+
|
|
94
|
+
/* Execute the child process but do not print any std output */
|
|
95
|
+
try {
|
|
96
|
+
childProcess.execSync(gitInitCommands, { stdio: 'pipe', cwd: functionDir });
|
|
97
|
+
childProcess.execSync(gitPullCommands, { stdio: 'pipe', cwd: functionDir });
|
|
98
|
+
} catch (error) {
|
|
99
|
+
/* Specialised errors with recommended actions to take */
|
|
100
|
+
if (error.message.includes('error: unknown option')) {
|
|
101
|
+
throw new Error(`${error.message} \n\nSuggestion: Try updating your git to the latest version, then trying to run this command again.`)
|
|
102
|
+
} else if (error.message.includes('is not recognized as an internal or external command,') || error.message.includes('command not found')) {
|
|
103
|
+
throw new Error(`${error.message} \n\nSuggestion: It appears that git is not installed, try installing git then trying to run this command again.`)
|
|
104
|
+
} else {
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
120
107
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
108
|
+
|
|
109
|
+
fs.rmSync(path.join(functionDir, ".git"), { recursive: true });
|
|
110
|
+
const copyRecursiveSync = (src, dest) => {
|
|
111
|
+
let exists = fs.existsSync(src);
|
|
112
|
+
let stats = exists && fs.statSync(src);
|
|
113
|
+
let isDirectory = exists && stats.isDirectory();
|
|
114
|
+
if (isDirectory) {
|
|
115
|
+
if (!fs.existsSync(dest)) {
|
|
116
|
+
fs.mkdirSync(dest);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fs.readdirSync(src).forEach(function (childItemName) {
|
|
120
|
+
copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
|
|
121
|
+
});
|
|
122
|
+
} else {
|
|
123
|
+
fs.copyFileSync(src, dest);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
copyRecursiveSync(path.join(functionDir, answers.runtime.id), functionDir);
|
|
127
|
+
|
|
128
|
+
fs.rmSync(`${functionDir}/${answers.runtime.id}`, { recursive: true, force: true });
|
|
129
|
+
|
|
130
|
+
const readmePath = path.join(process.cwd(), 'functions', answers.name, 'README.md');
|
|
131
|
+
const readmeFile = fs.readFileSync(readmePath).toString();
|
|
132
|
+
const newReadmeFile = readmeFile.split('\n');
|
|
133
|
+
newReadmeFile[0] = `# ${answers.name}`;
|
|
134
|
+
newReadmeFile.splice(1, 2);
|
|
135
|
+
fs.writeFileSync(readmePath, newReadmeFile.join('\n'));
|
|
136
|
+
|
|
137
|
+
let data = {
|
|
138
|
+
$id: response['$id'],
|
|
139
|
+
name: response.name,
|
|
140
|
+
runtime: response.runtime,
|
|
141
|
+
path: `functions/${answers.name}`,
|
|
142
|
+
entrypoint: answers.runtime.entrypoint || '',
|
|
143
|
+
ignore: answers.runtime.ignore || null,
|
|
144
|
+
execute: response.execute,
|
|
145
|
+
events: response.events,
|
|
146
|
+
schedule: response.schedule,
|
|
147
|
+
timeout: response.timeout,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
localConfig.addFunction(data);
|
|
151
|
+
success();
|
|
148
152
|
}
|
|
149
153
|
|
|
150
154
|
const initCollection = async ({ all, databaseId } = {}) => {
|
|
151
|
-
|
|
155
|
+
const databaseIds = [];
|
|
156
|
+
|
|
157
|
+
if (databaseId) {
|
|
158
|
+
databaseIds.push(databaseId);
|
|
159
|
+
} else if (all) {
|
|
160
|
+
let allDatabases = await databasesList({
|
|
161
|
+
parseOutput: false
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
databaseIds.push(...allDatabases.databases.map((d) => d.$id));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (databaseIds.length <= 0) {
|
|
168
|
+
let answers = await inquirer.prompt(questionsInitCollection)
|
|
169
|
+
if (!answers.databases) process.exit(1)
|
|
170
|
+
databaseIds.push(...answers.databases);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
for (const databaseId of databaseIds) {
|
|
174
|
+
const database = await databasesGet({
|
|
175
|
+
databaseId,
|
|
176
|
+
parseOutput: false
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
localConfig.addDatabase(database);
|
|
180
|
+
|
|
181
|
+
// TODO: Pagination?
|
|
182
|
+
let response = await databasesListCollections({
|
|
183
|
+
databaseId,
|
|
184
|
+
queries: ['limit(100)'],
|
|
185
|
+
parseOutput: false
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
let collections = response.collections;
|
|
189
|
+
log(`Found ${collections.length} collections`);
|
|
190
|
+
|
|
191
|
+
collections.forEach(async collection => {
|
|
192
|
+
log(`Fetching ${collection.name} ...`);
|
|
193
|
+
localConfig.addCollection({
|
|
194
|
+
...collection,
|
|
195
|
+
'$createdAt': undefined,
|
|
196
|
+
'$updatedAt': undefined,
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
success();
|
|
202
|
+
}
|
|
152
203
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
204
|
+
const initBucket = async () => {
|
|
205
|
+
// TODO: Pagination?
|
|
206
|
+
let response = await storageListBuckets({
|
|
207
|
+
queries: ['limit(100)'],
|
|
157
208
|
parseOutput: false
|
|
158
|
-
|
|
209
|
+
})
|
|
159
210
|
|
|
160
|
-
|
|
161
|
-
|
|
211
|
+
let buckets = response.buckets;
|
|
212
|
+
log(`Found ${buckets.length} buckets`);
|
|
162
213
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
214
|
+
buckets.forEach(async bucket => {
|
|
215
|
+
log(`Fetching ${bucket.name} ...`);
|
|
216
|
+
localConfig.addBucket(bucket);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
success();
|
|
220
|
+
}
|
|
168
221
|
|
|
169
|
-
|
|
222
|
+
const initTeam = async () => {
|
|
170
223
|
// TODO: Pagination?
|
|
171
|
-
let response = await
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
parseOutput: false
|
|
224
|
+
let response = await teamsList({
|
|
225
|
+
queries: ['limit(100)'],
|
|
226
|
+
parseOutput: false
|
|
175
227
|
})
|
|
176
228
|
|
|
177
|
-
let
|
|
178
|
-
log(`Found ${
|
|
229
|
+
let teams = response.teams;
|
|
230
|
+
log(`Found ${teams.length} teams`);
|
|
179
231
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
232
|
+
teams.forEach(async team => {
|
|
233
|
+
log(`Fetching ${team.name} ...`);
|
|
234
|
+
const { total, $updatedAt, $createdAt, prefs, ...rest } = team;
|
|
235
|
+
localConfig.addTeam(rest);
|
|
183
236
|
});
|
|
184
|
-
}
|
|
185
237
|
|
|
186
|
-
|
|
238
|
+
success();
|
|
187
239
|
}
|
|
188
240
|
|
|
189
241
|
init
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
242
|
+
.command("project")
|
|
243
|
+
.description("Initialise your Appwrite project")
|
|
244
|
+
.action(actionRunner(initProject));
|
|
245
|
+
|
|
246
|
+
init
|
|
247
|
+
.command("function")
|
|
248
|
+
.description("Initialise your Appwrite cloud function")
|
|
249
|
+
.action(actionRunner(initFunction))
|
|
250
|
+
|
|
251
|
+
init
|
|
252
|
+
.command("collection")
|
|
253
|
+
.description("Initialise your Appwrite collections")
|
|
254
|
+
.option(`--databaseId <databaseId>`, `Database ID`)
|
|
255
|
+
.option(`--all`, `Flag to initialize all databases`)
|
|
256
|
+
.action(actionRunner(initCollection))
|
|
193
257
|
|
|
194
258
|
init
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
259
|
+
.command("bucket")
|
|
260
|
+
.description("Initialise your Appwrite buckets")
|
|
261
|
+
.action(actionRunner(initBucket))
|
|
198
262
|
|
|
199
263
|
init
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
.option(`--all`, `Flag to initialize all databases`)
|
|
204
|
-
.action(actionRunner(initCollection))
|
|
264
|
+
.command("team")
|
|
265
|
+
.description("Initialise your Appwrite teams")
|
|
266
|
+
.action(actionRunner(initTeam))
|
|
205
267
|
|
|
206
268
|
module.exports = {
|
|
207
|
-
|
|
269
|
+
init,
|
|
208
270
|
};
|
package/lib/commands/locale.js
CHANGED
|
@@ -10,7 +10,9 @@ const { sdkForProject, sdkForConsole } = require('../sdks')
|
|
|
10
10
|
const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
|
|
11
11
|
const { localConfig, globalConfig } = require("../config");
|
|
12
12
|
|
|
13
|
-
const locale = new Command("locale").description(commandDescriptions['locale'])
|
|
13
|
+
const locale = new Command("locale").description(commandDescriptions['locale']).configureHelp({
|
|
14
|
+
helpWidth: process.stdout.columns || 80
|
|
15
|
+
})
|
|
14
16
|
|
|
15
17
|
const localeGet = async ({ parseOutput = true, sdk = undefined}) => {
|
|
16
18
|
|