appwrite-cli 0.16.0 → 0.18.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 -16
- package/docs/examples/account/{create-session.md → create-email-session.md} +1 -1
- package/docs/examples/account/create-phone-session.md +3 -0
- package/docs/examples/account/create-phone-verification.md +1 -0
- package/docs/examples/account/update-phone-session.md +3 -0
- package/docs/examples/account/update-phone-verification.md +3 -0
- package/docs/examples/account/update-phone.md +3 -0
- package/docs/examples/account/update-status.md +1 -0
- package/docs/examples/{database → databases}/create-boolean-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-collection.md +2 -1
- package/docs/examples/{database → databases}/create-document.md +2 -1
- package/docs/examples/{database → databases}/create-email-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-enum-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-float-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-index.md +2 -1
- package/docs/examples/{database → databases}/create-integer-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-ip-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-string-attribute.md +2 -1
- package/docs/examples/{database → databases}/create-url-attribute.md +2 -1
- package/docs/examples/databases/create.md +3 -0
- package/docs/examples/databases/delete-attribute.md +4 -0
- package/docs/examples/databases/delete-collection.md +3 -0
- package/docs/examples/{database → databases}/delete-document.md +2 -1
- package/docs/examples/databases/delete-index.md +4 -0
- package/docs/examples/databases/delete.md +2 -0
- package/docs/examples/databases/get-attribute.md +4 -0
- package/docs/examples/databases/get-collection-usage.md +4 -0
- package/docs/examples/databases/get-collection.md +3 -0
- package/docs/examples/databases/get-database-usage.md +3 -0
- package/docs/examples/{database → databases}/get-document.md +2 -1
- package/docs/examples/databases/get-index.md +4 -0
- package/docs/examples/databases/get-usage.md +2 -0
- package/docs/examples/databases/get.md +2 -0
- package/docs/examples/databases/list-attributes.md +3 -0
- package/docs/examples/databases/list-collection-logs.md +5 -0
- package/docs/examples/databases/list-collections.md +8 -0
- package/docs/examples/{database → databases}/list-document-logs.md +2 -1
- package/docs/examples/databases/list-documents.md +10 -0
- package/docs/examples/databases/list-indexes.md +3 -0
- package/docs/examples/databases/list-logs.md +4 -0
- package/docs/examples/databases/list.md +7 -0
- package/docs/examples/{database → databases}/update-collection.md +2 -1
- package/docs/examples/{database → databases}/update-document.md +3 -2
- package/docs/examples/databases/update.md +3 -0
- package/docs/examples/projects/create-key.md +2 -1
- package/docs/examples/projects/update-key.md +2 -1
- package/docs/examples/projects/update-webhook-signature.md +3 -0
- package/docs/examples/teams/list-logs.md +4 -0
- package/docs/examples/users/get-memberships.md +2 -0
- package/docs/examples/users/{update-verification.md → update-email-verification.md} +1 -1
- package/docs/examples/users/update-phone-verification.md +3 -0
- package/docs/examples/users/update-phone.md +3 -0
- package/index.js +2 -2
- package/install.ps1 +9 -5
- package/install.sh +1 -1
- package/lib/client.js +6 -7
- package/lib/commands/account.js +230 -56
- package/lib/commands/avatars.js +12 -9
- package/lib/commands/{database.js → databases.js} +484 -181
- package/lib/commands/deploy.js +156 -73
- package/lib/commands/functions.js +26 -9
- package/lib/commands/generic.js +13 -6
- package/lib/commands/health.js +3 -23
- package/lib/commands/init.js +43 -24
- package/lib/commands/locale.js +3 -0
- package/lib/commands/projects.js +50 -8
- package/lib/commands/storage.js +8 -5
- package/lib/commands/teams.js +45 -5
- package/lib/commands/users.js +101 -7
- package/lib/config.js +6 -4
- package/lib/parser.js +1 -1
- package/lib/questions.js +87 -4
- package/lib/sdks.js +17 -1
- package/lib/utils.js +19 -0
- package/package.json +8 -6
- package/docs/examples/account/delete.md +0 -1
- package/docs/examples/database/delete-attribute.md +0 -3
- package/docs/examples/database/delete-collection.md +0 -2
- package/docs/examples/database/delete-index.md +0 -3
- package/docs/examples/database/get-attribute.md +0 -3
- package/docs/examples/database/get-collection-usage.md +0 -3
- package/docs/examples/database/get-collection.md +0 -2
- package/docs/examples/database/get-index.md +0 -3
- package/docs/examples/database/get-usage.md +0 -2
- package/docs/examples/database/list-attributes.md +0 -2
- package/docs/examples/database/list-collection-logs.md +0 -4
- package/docs/examples/database/list-collections.md +0 -7
- package/docs/examples/database/list-documents.md +0 -9
- package/docs/examples/database/list-indexes.md +0 -2
- package/docs/examples/health/get-queue-usage.md +0 -1
package/lib/commands/deploy.js
CHANGED
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
const inquirer = require("inquirer");
|
|
2
|
+
const JSONbig = require("json-bigint")({ storeAsString: false });
|
|
2
3
|
const { Command } = require("commander");
|
|
3
4
|
const { localConfig } = require("../config");
|
|
4
5
|
const { questionsDeployFunctions, questionsGetEntrypoint, questionsDeployCollections } = require("../questions");
|
|
5
6
|
const { actionRunner, success, log, error, commandDescriptions } = require("../parser");
|
|
6
7
|
const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment } = require('./functions');
|
|
7
8
|
const {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
databasesGet,
|
|
10
|
+
databasesCreate,
|
|
11
|
+
databasesCreateBooleanAttribute,
|
|
12
|
+
databasesGetCollection,
|
|
13
|
+
databasesCreateCollection,
|
|
14
|
+
databasesCreateStringAttribute,
|
|
15
|
+
databasesCreateIntegerAttribute,
|
|
16
|
+
databasesCreateFloatAttribute,
|
|
17
|
+
databasesCreateEmailAttribute,
|
|
18
|
+
databasesCreateIndex,
|
|
19
|
+
databasesCreateUrlAttribute,
|
|
20
|
+
databasesCreateIpAttribute,
|
|
21
|
+
databasesCreateEnumAttribute,
|
|
22
|
+
databasesDeleteAttribute,
|
|
23
|
+
databasesListAttributes,
|
|
24
|
+
databasesListIndexes,
|
|
25
|
+
databasesDeleteIndex
|
|
26
|
+
} = require("./databases");
|
|
24
27
|
|
|
25
28
|
const POOL_DEBOUNCE = 2000; // in milliseconds
|
|
26
29
|
const POOL_MAX_DEBOUNCES = 30;
|
|
27
30
|
|
|
28
31
|
const awaitPools = {
|
|
29
|
-
wipeAttributes: async (collectionId, iteration = 1) => {
|
|
32
|
+
wipeAttributes: async (databaseId, collectionId, iteration = 1) => {
|
|
30
33
|
if (iteration > POOL_MAX_DEBOUNCES) {
|
|
31
34
|
return false;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
// TODO: Pagination?
|
|
35
|
-
const { attributes: remoteAttributes } = await
|
|
38
|
+
const { attributes: remoteAttributes } = await databasesListAttributes({
|
|
39
|
+
databaseId,
|
|
36
40
|
collectionId,
|
|
37
41
|
limit: 100,
|
|
38
42
|
parseOutput: false
|
|
@@ -43,15 +47,16 @@ const awaitPools = {
|
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
|
|
46
|
-
return await awaitPools.wipeAttributes(collectionId, iteration + 1);
|
|
50
|
+
return await awaitPools.wipeAttributes(databaseId, collectionId, iteration + 1);
|
|
47
51
|
},
|
|
48
|
-
wipeIndexes: async (collectionId, iteration = 1) => {
|
|
52
|
+
wipeIndexes: async (databaseId, collectionId, iteration = 1) => {
|
|
49
53
|
if (iteration > POOL_MAX_DEBOUNCES) {
|
|
50
54
|
return false;
|
|
51
55
|
}
|
|
52
56
|
|
|
53
57
|
// TODO: Pagination?
|
|
54
|
-
const { indexes: remoteIndexes } = await
|
|
58
|
+
const { indexes: remoteIndexes } = await databasesListIndexes({
|
|
59
|
+
databaseId,
|
|
55
60
|
collectionId,
|
|
56
61
|
limit: 100,
|
|
57
62
|
parseOutput: false
|
|
@@ -62,15 +67,16 @@ const awaitPools = {
|
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
|
|
65
|
-
return await awaitPools.wipeIndexes(collectionId, iteration + 1);
|
|
70
|
+
return await awaitPools.wipeIndexes(databaseId, collectionId, iteration + 1);
|
|
66
71
|
},
|
|
67
|
-
expectAttributes: async (collectionId, attributeKeys, iteration = 1) => {
|
|
72
|
+
expectAttributes: async (databaseId, collectionId, attributeKeys, iteration = 1) => {
|
|
68
73
|
if (iteration > POOL_MAX_DEBOUNCES) {
|
|
69
74
|
return false;
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
// TODO: Pagination?
|
|
73
|
-
const { attributes: remoteAttributes } = await
|
|
78
|
+
const { attributes: remoteAttributes } = await databasesListAttributes({
|
|
79
|
+
databaseId,
|
|
74
80
|
collectionId,
|
|
75
81
|
limit: 100,
|
|
76
82
|
parseOutput: false
|
|
@@ -93,15 +99,16 @@ const awaitPools = {
|
|
|
93
99
|
}
|
|
94
100
|
|
|
95
101
|
await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
|
|
96
|
-
return await awaitPools.expectAttributes(collectionId, attributeKeys, iteration + 1);
|
|
102
|
+
return await awaitPools.expectAttributes(databaseId, collectionId, attributeKeys, iteration + 1);
|
|
97
103
|
},
|
|
98
|
-
expectIndexes: async (collectionId, indexKeys, iteration = 1) => {
|
|
104
|
+
expectIndexes: async (databaseId, collectionId, indexKeys, iteration = 1) => {
|
|
99
105
|
if (iteration > POOL_MAX_DEBOUNCES) {
|
|
100
106
|
return false;
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
// TODO: Pagination?
|
|
104
|
-
const { indexes: remoteIndexes } = await
|
|
110
|
+
const { indexes: remoteIndexes } = await databasesListIndexes({
|
|
111
|
+
databaseId,
|
|
105
112
|
collectionId,
|
|
106
113
|
limit: 100,
|
|
107
114
|
parseOutput: false
|
|
@@ -124,32 +131,49 @@ const awaitPools = {
|
|
|
124
131
|
}
|
|
125
132
|
|
|
126
133
|
await new Promise(resolve => setTimeout(resolve, POOL_DEBOUNCE));
|
|
127
|
-
return await awaitPools.expectIndexes(collectionId, indexKeys, iteration + 1);
|
|
134
|
+
return await awaitPools.expectIndexes(databaseId, collectionId, indexKeys, iteration + 1);
|
|
128
135
|
},
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
const deploy = new Command("deploy")
|
|
132
139
|
.description(commandDescriptions['deploy'])
|
|
133
|
-
.
|
|
134
|
-
|
|
135
|
-
if (all == undefined) {
|
|
136
|
-
command.help()
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
await deployFunction();
|
|
141
|
-
} catch (e) {
|
|
142
|
-
error(e.message);
|
|
143
|
-
}
|
|
144
|
-
await deployCollection()
|
|
140
|
+
.action(actionRunner(async (_options, command) => {
|
|
141
|
+
command.help()
|
|
145
142
|
}));
|
|
146
143
|
|
|
147
|
-
const deployFunction = async () => {
|
|
144
|
+
const deployFunction = async ({ functionId, all } = {}) => {
|
|
148
145
|
let response = {};
|
|
149
146
|
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
const functionIds = [];
|
|
148
|
+
|
|
149
|
+
if(functionId) {
|
|
150
|
+
functionIds.push(functionId);
|
|
151
|
+
} else if(all) {
|
|
152
|
+
const functions = localConfig.getFunctions();
|
|
153
|
+
if (functions.length === 0) {
|
|
154
|
+
throw new Error("No functions found in the current directory.");
|
|
155
|
+
}
|
|
156
|
+
functionIds.push(...functions.map((func, idx) => {
|
|
157
|
+
return func.$id;
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
152
160
|
|
|
161
|
+
if(functionIds.length <= 0) {
|
|
162
|
+
const answers = await inquirer.prompt(questionsDeployFunctions);
|
|
163
|
+
functionIds.push(...answers.functions);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
let functions = functionIds.map((id) => {
|
|
167
|
+
const functions = localConfig.getFunctions();
|
|
168
|
+
const func = functions.find((f) => f.$id === id);
|
|
169
|
+
|
|
170
|
+
if(!func) {
|
|
171
|
+
throw new Error("Function '" + id + "' not found.")
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return func;
|
|
175
|
+
});
|
|
176
|
+
|
|
153
177
|
for (let func of functions) {
|
|
154
178
|
log(`Deploying function ${func.name} ( ${func['$id']} )`)
|
|
155
179
|
|
|
@@ -167,7 +191,7 @@ const deployFunction = async () => {
|
|
|
167
191
|
functionId: func['$id'],
|
|
168
192
|
name: func.name,
|
|
169
193
|
execute: func.execute,
|
|
170
|
-
vars: response.vars,
|
|
194
|
+
vars: JSON.stringify(response.vars),
|
|
171
195
|
events: func.events,
|
|
172
196
|
schedule: func.schedule,
|
|
173
197
|
timeout: func.timeout,
|
|
@@ -181,7 +205,7 @@ const deployFunction = async () => {
|
|
|
181
205
|
name: func.name,
|
|
182
206
|
runtime: func.runtime,
|
|
183
207
|
execute: func.execute,
|
|
184
|
-
vars: func.vars,
|
|
208
|
+
vars: JSON.stringify(func.vars),
|
|
185
209
|
events: func.events,
|
|
186
210
|
schedule: func.schedule,
|
|
187
211
|
timeout: func.timeout,
|
|
@@ -229,12 +253,13 @@ const deployFunction = async () => {
|
|
|
229
253
|
}
|
|
230
254
|
}
|
|
231
255
|
|
|
232
|
-
const createAttribute = async (collectionId, attribute) => {
|
|
256
|
+
const createAttribute = async (databaseId, collectionId, attribute) => {
|
|
233
257
|
switch (attribute.type) {
|
|
234
258
|
case 'string':
|
|
235
259
|
switch (attribute.format) {
|
|
236
260
|
case 'email':
|
|
237
|
-
return await
|
|
261
|
+
return await databasesCreateEmailAttribute({
|
|
262
|
+
databaseId,
|
|
238
263
|
collectionId,
|
|
239
264
|
key: attribute.key,
|
|
240
265
|
required: attribute.required,
|
|
@@ -243,7 +268,8 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
243
268
|
parseOutput: false
|
|
244
269
|
})
|
|
245
270
|
case 'url':
|
|
246
|
-
return await
|
|
271
|
+
return await databasesCreateUrlAttribute({
|
|
272
|
+
databaseId,
|
|
247
273
|
collectionId,
|
|
248
274
|
key: attribute.key,
|
|
249
275
|
required: attribute.required,
|
|
@@ -252,7 +278,8 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
252
278
|
parseOutput: false
|
|
253
279
|
})
|
|
254
280
|
case 'ip':
|
|
255
|
-
return await
|
|
281
|
+
return await databasesCreateIpAttribute({
|
|
282
|
+
databaseId,
|
|
256
283
|
collectionId,
|
|
257
284
|
key: attribute.key,
|
|
258
285
|
required: attribute.required,
|
|
@@ -261,7 +288,8 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
261
288
|
parseOutput: false
|
|
262
289
|
})
|
|
263
290
|
case 'enum':
|
|
264
|
-
return await
|
|
291
|
+
return await databasesCreateEnumAttribute({
|
|
292
|
+
databaseId,
|
|
265
293
|
collectionId,
|
|
266
294
|
key: attribute.key,
|
|
267
295
|
elements: attribute.elements,
|
|
@@ -271,7 +299,8 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
271
299
|
parseOutput: false
|
|
272
300
|
})
|
|
273
301
|
default:
|
|
274
|
-
return await
|
|
302
|
+
return await databasesCreateStringAttribute({
|
|
303
|
+
databaseId,
|
|
275
304
|
collectionId,
|
|
276
305
|
key: attribute.key,
|
|
277
306
|
size: attribute.size,
|
|
@@ -283,7 +312,8 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
283
312
|
|
|
284
313
|
}
|
|
285
314
|
case 'integer':
|
|
286
|
-
return await
|
|
315
|
+
return await databasesCreateIntegerAttribute({
|
|
316
|
+
databaseId,
|
|
287
317
|
collectionId,
|
|
288
318
|
key: attribute.key,
|
|
289
319
|
required: attribute.required,
|
|
@@ -294,7 +324,8 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
294
324
|
parseOutput: false
|
|
295
325
|
})
|
|
296
326
|
case 'double':
|
|
297
|
-
return
|
|
327
|
+
return databasesCreateFloatAttribute({
|
|
328
|
+
databaseId,
|
|
298
329
|
collectionId,
|
|
299
330
|
key: attribute.key,
|
|
300
331
|
required: attribute.required,
|
|
@@ -305,7 +336,9 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
305
336
|
parseOutput: false
|
|
306
337
|
})
|
|
307
338
|
case 'boolean':
|
|
308
|
-
return
|
|
339
|
+
return databasesCreateBooleanAttribute({
|
|
340
|
+
databaseId,
|
|
341
|
+
databaseId,
|
|
309
342
|
collectionId,
|
|
310
343
|
key: attribute.key,
|
|
311
344
|
required: attribute.required,
|
|
@@ -316,15 +349,55 @@ const createAttribute = async (collectionId, attribute) => {
|
|
|
316
349
|
}
|
|
317
350
|
}
|
|
318
351
|
|
|
319
|
-
const deployCollection = async () => {
|
|
352
|
+
const deployCollection = async ({ all } = {}) => {
|
|
320
353
|
let response = {};
|
|
321
|
-
|
|
322
|
-
let
|
|
354
|
+
|
|
355
|
+
let collectionIds = [];
|
|
356
|
+
const configCollections = localConfig.getCollections();
|
|
357
|
+
|
|
358
|
+
if(all) {
|
|
359
|
+
if (configCollections.length === 0) {
|
|
360
|
+
throw new Error("No collections found in the current directory. Run `appwrite init collection` to fetch all your collections.");
|
|
361
|
+
}
|
|
362
|
+
collectionIds.push(...configCollections.map((c) => c.$id));
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if(collectionIds.length <= 0) {
|
|
366
|
+
let answers = await inquirer.prompt(questionsDeployCollections[0])
|
|
367
|
+
collectionIds.push(...answers.collections);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
let collections = [];
|
|
371
|
+
|
|
372
|
+
for(const collectionId of collectionIds) {
|
|
373
|
+
const idCollections = configCollections.filter((c) => c.$id === collectionId);
|
|
374
|
+
collections.push(...idCollections);
|
|
375
|
+
}
|
|
323
376
|
|
|
324
377
|
for (let collection of collections) {
|
|
325
378
|
log(`Deploying collection ${collection.name} ( ${collection['$id']} )`)
|
|
379
|
+
|
|
380
|
+
let databaseId;
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
const database = await databasesGet({
|
|
384
|
+
databaseId: collection.databaseId,
|
|
385
|
+
parseOutput: false,
|
|
386
|
+
});
|
|
387
|
+
databaseId = database.$id;
|
|
388
|
+
} catch(err) {
|
|
389
|
+
log(`Database ${collection.databaseId} not found. Creating it now...`);
|
|
390
|
+
const database = await databasesCreate({
|
|
391
|
+
databaseId: collection.databaseId,
|
|
392
|
+
name: collection.databaseId,
|
|
393
|
+
parseOutput: false,
|
|
394
|
+
});
|
|
395
|
+
databaseId = database.$id;
|
|
396
|
+
}
|
|
397
|
+
|
|
326
398
|
try {
|
|
327
|
-
response = await
|
|
399
|
+
response = await databasesGetCollection({
|
|
400
|
+
databaseId,
|
|
328
401
|
collectionId: collection['$id'],
|
|
329
402
|
parseOutput: false,
|
|
330
403
|
})
|
|
@@ -339,51 +412,55 @@ const deployCollection = async () => {
|
|
|
339
412
|
log(`Updating attributes ... `);
|
|
340
413
|
|
|
341
414
|
// TODO: Pagination?
|
|
342
|
-
const { indexes: remoteIndexes } = await
|
|
415
|
+
const { indexes: remoteIndexes } = await databasesListIndexes({
|
|
416
|
+
databaseId,
|
|
343
417
|
collectionId: collection['$id'],
|
|
344
418
|
limit: 100,
|
|
345
419
|
parseOutput: false
|
|
346
420
|
});
|
|
347
421
|
|
|
348
422
|
await Promise.all(remoteIndexes.map(async index => {
|
|
349
|
-
await
|
|
423
|
+
await databasesDeleteIndex({
|
|
424
|
+
databaseId,
|
|
350
425
|
collectionId: collection['$id'],
|
|
351
426
|
key: index.key,
|
|
352
427
|
parseOutput: false
|
|
353
428
|
});
|
|
354
429
|
}));
|
|
355
430
|
|
|
356
|
-
const deleteIndexesPoolStatus = await awaitPools.wipeIndexes(collection['$id']);
|
|
431
|
+
const deleteIndexesPoolStatus = await awaitPools.wipeIndexes(databaseId, collection['$id']);
|
|
357
432
|
if (!deleteIndexesPoolStatus) {
|
|
358
433
|
throw new Error("Index deletion did not finish for too long.");
|
|
359
434
|
}
|
|
360
435
|
|
|
361
436
|
// TODO: Pagination?
|
|
362
|
-
const { attributes: remoteAttributes } = await
|
|
437
|
+
const { attributes: remoteAttributes } = await databasesListAttributes({
|
|
438
|
+
databaseId,
|
|
363
439
|
collectionId: collection['$id'],
|
|
364
440
|
limit: 100,
|
|
365
441
|
parseOutput: false
|
|
366
442
|
});
|
|
367
443
|
|
|
368
444
|
await Promise.all(remoteAttributes.map(async attribute => {
|
|
369
|
-
await
|
|
445
|
+
await databasesDeleteAttribute({
|
|
446
|
+
databaseId,
|
|
370
447
|
collectionId: collection['$id'],
|
|
371
448
|
key: attribute.key,
|
|
372
449
|
parseOutput: false
|
|
373
450
|
});
|
|
374
451
|
}));
|
|
375
452
|
|
|
376
|
-
const deleteAttributesPoolStatus = await awaitPools.wipeAttributes(collection['$id']);
|
|
453
|
+
const deleteAttributesPoolStatus = await awaitPools.wipeAttributes(databaseId, collection['$id']);
|
|
377
454
|
if (!deleteAttributesPoolStatus) {
|
|
378
455
|
throw new Error("Attribute deletion did not finish for too long.");
|
|
379
456
|
}
|
|
380
457
|
|
|
381
458
|
await Promise.all(collection.attributes.map(async attribute => {
|
|
382
|
-
await createAttribute(collection['$id'], attribute);
|
|
459
|
+
await createAttribute(databaseId, collection['$id'], attribute);
|
|
383
460
|
}));
|
|
384
461
|
|
|
385
462
|
const attributeKeys = collection.attributes.map(attribute => attribute.key);
|
|
386
|
-
const createPoolStatus = await awaitPools.expectAttributes(collection['$id'], attributeKeys);
|
|
463
|
+
const createPoolStatus = await awaitPools.expectAttributes(databaseId, collection['$id'], attributeKeys);
|
|
387
464
|
if (!createPoolStatus) {
|
|
388
465
|
throw new Error("Attribute creation did not finish for too long.");
|
|
389
466
|
}
|
|
@@ -392,7 +469,8 @@ const deployCollection = async () => {
|
|
|
392
469
|
|
|
393
470
|
log(`Creating indexes ...`)
|
|
394
471
|
await Promise.all(collection.indexes.map(async index => {
|
|
395
|
-
await
|
|
472
|
+
await databasesCreateIndex({
|
|
473
|
+
databaseId,
|
|
396
474
|
collectionId: collection['$id'],
|
|
397
475
|
key: index.key,
|
|
398
476
|
type: index.type,
|
|
@@ -403,7 +481,7 @@ const deployCollection = async () => {
|
|
|
403
481
|
}));
|
|
404
482
|
|
|
405
483
|
const indexKeys = collection.indexes.map(attribute => attribute.key);
|
|
406
|
-
const indexPoolStatus = await awaitPools.expectIndexes(collection['$id'], indexKeys);
|
|
484
|
+
const indexPoolStatus = await awaitPools.expectIndexes(databaseId, collection['$id'], indexKeys);
|
|
407
485
|
if (!indexPoolStatus) {
|
|
408
486
|
throw new Error("Index creation did not finish for too long.");
|
|
409
487
|
}
|
|
@@ -412,7 +490,8 @@ const deployCollection = async () => {
|
|
|
412
490
|
} catch (e) {
|
|
413
491
|
if (e.code == 404) {
|
|
414
492
|
log(`Collection ${collection.name} does not exist in the project. Creating ... `);
|
|
415
|
-
response = await
|
|
493
|
+
response = await databasesCreateCollection({
|
|
494
|
+
databaseId,
|
|
416
495
|
collectionId: collection['$id'],
|
|
417
496
|
name: collection.name,
|
|
418
497
|
permission: collection.permission,
|
|
@@ -423,11 +502,11 @@ const deployCollection = async () => {
|
|
|
423
502
|
|
|
424
503
|
log(`Creating attributes ... `);
|
|
425
504
|
await Promise.all(collection.attributes.map(async attribute => {
|
|
426
|
-
await createAttribute(collection['$id'], attribute);
|
|
505
|
+
await createAttribute(databaseId, collection['$id'], attribute);
|
|
427
506
|
}));
|
|
428
507
|
|
|
429
508
|
const attributeKeys = collection.attributes.map(attribute => attribute.key);
|
|
430
|
-
const attributePoolStatus = await awaitPools.expectAttributes(collection['$id'], attributeKeys);
|
|
509
|
+
const attributePoolStatus = await awaitPools.expectAttributes(databaseId, collection['$id'], attributeKeys);
|
|
431
510
|
if (!attributePoolStatus) {
|
|
432
511
|
throw new Error("Attribute creation did not finish for too long.");
|
|
433
512
|
}
|
|
@@ -436,7 +515,8 @@ const deployCollection = async () => {
|
|
|
436
515
|
|
|
437
516
|
log(`Creating indexes ...`);
|
|
438
517
|
await Promise.all(collection.indexes.map(async index => {
|
|
439
|
-
await
|
|
518
|
+
await databasesCreateIndex({
|
|
519
|
+
databaseId,
|
|
440
520
|
collectionId: collection['$id'],
|
|
441
521
|
key: index.key,
|
|
442
522
|
type: index.type,
|
|
@@ -447,7 +527,7 @@ const deployCollection = async () => {
|
|
|
447
527
|
}));
|
|
448
528
|
|
|
449
529
|
const indexKeys = collection.indexes.map(attribute => attribute.key);
|
|
450
|
-
const indexPoolStatus = await awaitPools.expectIndexes(collection['$id'], indexKeys);
|
|
530
|
+
const indexPoolStatus = await awaitPools.expectIndexes(databaseId, collection['$id'], indexKeys);
|
|
451
531
|
if (!indexPoolStatus) {
|
|
452
532
|
throw new Error("Index creation did not finish for too long.");
|
|
453
533
|
}
|
|
@@ -465,11 +545,14 @@ const deployCollection = async () => {
|
|
|
465
545
|
deploy
|
|
466
546
|
.command("function")
|
|
467
547
|
.description("Deploy functions in the current directory.")
|
|
548
|
+
.option(`--functionId <functionId>`, `Function ID`)
|
|
549
|
+
.option(`--all`, `Flag to deploy all functions`)
|
|
468
550
|
.action(actionRunner(deployFunction));
|
|
469
551
|
|
|
470
552
|
deploy
|
|
471
553
|
.command("collection")
|
|
472
554
|
.description("Deploy collections in the current project.")
|
|
555
|
+
.option(`--all`, `Flag to deploy all functions`)
|
|
473
556
|
.action(actionRunner(deployCollection));
|
|
474
557
|
|
|
475
558
|
module.exports = {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
+
const pathLib = require('path');
|
|
2
3
|
const tar = require("tar");
|
|
4
|
+
const ignore = require("ignore");
|
|
3
5
|
const { promisify } = require('util');
|
|
4
6
|
const libClient = require('../client.js');
|
|
7
|
+
const { getAllFiles } = require('../utils.js');
|
|
5
8
|
const { Command } = require('commander');
|
|
6
9
|
const { sdkForProject, sdkForConsole } = require('../sdks')
|
|
7
10
|
const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
|
|
@@ -261,7 +264,7 @@ const functionsListDeployments = async ({ functionId, search, limit, offset, cur
|
|
|
261
264
|
const functionsCreateDeployment = async ({ functionId, entrypoint, code, activate, parseOutput = true, sdk = undefined, onProgress = () => {}}) => {
|
|
262
265
|
/* @param {string} functionId */
|
|
263
266
|
/* @param {string} entrypoint */
|
|
264
|
-
/* @param {
|
|
267
|
+
/* @param {InputFile} code */
|
|
265
268
|
/* @param {boolean} activate */
|
|
266
269
|
|
|
267
270
|
let client = !sdk ? await sdkForProject() : sdk;
|
|
@@ -277,13 +280,27 @@ const functionsCreateDeployment = async ({ functionId, entrypoint, code, activat
|
|
|
277
280
|
if (!fs.lstatSync(folderPath).isDirectory())
|
|
278
281
|
throw new Error('The path is not a directory.');
|
|
279
282
|
|
|
283
|
+
const ignorer = ignore();
|
|
284
|
+
|
|
285
|
+
const func = localConfig.getFunction(functionId);
|
|
286
|
+
|
|
287
|
+
if(func.ignore) {
|
|
288
|
+
ignorer.add(func.ignore);
|
|
289
|
+
log('Ignoring files using configuration from appwrite.json');
|
|
290
|
+
} else if(fs.existsSync(pathLib.join(code, '.gitignore'))) {
|
|
291
|
+
ignorer.add(fs.readFileSync(pathLib.join(code, '.gitignore')).toString());
|
|
292
|
+
log('Ignoring files in .gitignore');
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const files = getAllFiles(code).map((file) => pathLib.relative(code, file)).filter((file) => !ignorer.ignores(file));
|
|
296
|
+
|
|
280
297
|
await tar
|
|
281
298
|
.create({
|
|
282
299
|
gzip: true,
|
|
283
300
|
sync: true,
|
|
284
301
|
cwd: folderPath,
|
|
285
302
|
file: 'code.tar.gz'
|
|
286
|
-
},
|
|
303
|
+
}, files);
|
|
287
304
|
let archivePath = fs.realpathSync('code.tar.gz')
|
|
288
305
|
if (typeof archivePath !== 'undefined') {
|
|
289
306
|
payload['code'] = archivePath;
|
|
@@ -559,7 +576,7 @@ functions
|
|
|
559
576
|
.option(`--limit <limit>`, `Maximum number of functions to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
|
|
560
577
|
.option(`--offset <offset>`, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
|
|
561
578
|
.option(`--cursor <cursor>`, `ID of the function used as the starting point for the query, excluding the function itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
|
|
562
|
-
.option(`--cursorDirection <cursorDirection>`, `Direction of the cursor.`)
|
|
579
|
+
.option(`--cursorDirection <cursorDirection>`, `Direction of the cursor, can be either 'before' or 'after'.`)
|
|
563
580
|
.option(`--orderType <orderType>`, `Order result by ASC or DESC order.`)
|
|
564
581
|
.action(actionRunner(functionsList))
|
|
565
582
|
|
|
@@ -568,10 +585,10 @@ functions
|
|
|
568
585
|
.description(`Create a new function. You can pass a list of [permissions](/docs/permissions) to allow different project users or team with access to execute the function using the client API.`)
|
|
569
586
|
.requiredOption(`--functionId <functionId>`, `Function ID. Choose your own unique ID or pass the string "unique()" to auto generate it. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.`)
|
|
570
587
|
.requiredOption(`--name <name>`, `Function name. Max length: 128 chars.`)
|
|
571
|
-
.requiredOption(`--execute <execute...>`, `An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
|
|
588
|
+
.requiredOption(`--execute <execute...>`, `An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions. Maximum of 100 scopes are allowed, each 64 characters long.`)
|
|
572
589
|
.requiredOption(`--runtime <runtime>`, `Execution runtime.`)
|
|
573
590
|
.option(`--vars <vars>`, `Key-value JSON object that will be passed to the function as environment variables.`)
|
|
574
|
-
.option(`--events <events...>`, `Events list.`)
|
|
591
|
+
.option(`--events <events...>`, `Events list. Maximum of 100 events are allowed.`)
|
|
575
592
|
.option(`--schedule <schedule>`, `Schedule CRON syntax.`)
|
|
576
593
|
.option(`--timeout <timeout>`, `Function maximum execution time in seconds.`, parseInteger)
|
|
577
594
|
.action(actionRunner(functionsCreate))
|
|
@@ -592,9 +609,9 @@ functions
|
|
|
592
609
|
.description(`Update function by its unique ID.`)
|
|
593
610
|
.requiredOption(`--functionId <functionId>`, `Function ID.`)
|
|
594
611
|
.requiredOption(`--name <name>`, `Function name. Max length: 128 chars.`)
|
|
595
|
-
.requiredOption(`--execute <execute...>`, `An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.`)
|
|
612
|
+
.requiredOption(`--execute <execute...>`, `An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions. Maximum of 100 scopes are allowed, each 64 characters long.`)
|
|
596
613
|
.option(`--vars <vars>`, `Key-value JSON object that will be passed to the function as environment variables.`)
|
|
597
|
-
.option(`--events <events...>`, `Events list.`)
|
|
614
|
+
.option(`--events <events...>`, `Events list. Maximum of 100 events are allowed.`)
|
|
598
615
|
.option(`--schedule <schedule>`, `Schedule CRON syntax.`)
|
|
599
616
|
.option(`--timeout <timeout>`, `Maximum execution time in seconds.`, parseInteger)
|
|
600
617
|
.action(actionRunner(functionsUpdate))
|
|
@@ -613,7 +630,7 @@ functions
|
|
|
613
630
|
.option(`--limit <limit>`, `Maximum number of deployments to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.`, parseInteger)
|
|
614
631
|
.option(`--offset <offset>`, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
|
|
615
632
|
.option(`--cursor <cursor>`, `ID of the deployment used as the starting point for the query, excluding the deployment itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
|
|
616
|
-
.option(`--cursorDirection <cursorDirection>`, `Direction of the cursor.`)
|
|
633
|
+
.option(`--cursorDirection <cursorDirection>`, `Direction of the cursor, can be either 'before' or 'after'.`)
|
|
617
634
|
.option(`--orderType <orderType>`, `Order result by ASC or DESC order.`)
|
|
618
635
|
.action(actionRunner(functionsListDeployments))
|
|
619
636
|
|
|
@@ -663,7 +680,7 @@ functions
|
|
|
663
680
|
.option(`--offset <offset>`, `Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)`, parseInteger)
|
|
664
681
|
.option(`--search <search>`, `Search term to filter your list results. Max length: 256 chars.`)
|
|
665
682
|
.option(`--cursor <cursor>`, `ID of the execution used as the starting point for the query, excluding the execution itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)`)
|
|
666
|
-
.option(`--cursorDirection <cursorDirection>`, `Direction of the cursor.`)
|
|
683
|
+
.option(`--cursorDirection <cursorDirection>`, `Direction of the cursor, can be either 'before' or 'after'.`)
|
|
667
684
|
.action(actionRunner(functionsListExecutions))
|
|
668
685
|
|
|
669
686
|
functions
|
package/lib/commands/generic.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const inquirer = require("inquirer");
|
|
2
2
|
const { Command } = require("commander");
|
|
3
|
+
const Client = require("../client");
|
|
3
4
|
const { sdkForConsole } = require("../sdks");
|
|
4
5
|
const { globalConfig, localConfig } = require("../config");
|
|
5
6
|
const { actionRunner, success, parseBool, commandDescriptions, log, parse } = require("../parser");
|
|
6
7
|
const { questionsLogin } = require("../questions");
|
|
7
|
-
const {
|
|
8
|
+
const { accountCreateEmailSession, accountDeleteSession } = require("./account");
|
|
8
9
|
|
|
9
10
|
const login = new Command("login")
|
|
10
11
|
.description(commandDescriptions['login'])
|
|
@@ -13,7 +14,7 @@ const login = new Command("login")
|
|
|
13
14
|
|
|
14
15
|
let client = await sdkForConsole(false);
|
|
15
16
|
|
|
16
|
-
await
|
|
17
|
+
await accountCreateEmailSession({
|
|
17
18
|
email: answers.email,
|
|
18
19
|
password: answers.password,
|
|
19
20
|
parseOutput: false,
|
|
@@ -65,13 +66,19 @@ const client = new Command("client")
|
|
|
65
66
|
if (endpoint !== undefined) {
|
|
66
67
|
try {
|
|
67
68
|
let url = new URL(endpoint);
|
|
68
|
-
if (url.protocol
|
|
69
|
-
globalConfig.setEndpoint(endpoint);
|
|
70
|
-
} else {
|
|
69
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
71
70
|
throw new Error();
|
|
72
71
|
}
|
|
72
|
+
|
|
73
|
+
let client = new Client().setEndpoint(endpoint);
|
|
74
|
+
let response = await client.call('GET', '/health/version');
|
|
75
|
+
if(!response.version) {
|
|
76
|
+
throw new Error();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
globalConfig.setEndpoint(endpoint);
|
|
73
80
|
} catch (_) {
|
|
74
|
-
throw new Error("Invalid endpoint");
|
|
81
|
+
throw new Error("Invalid endpoint or your Appwrite server is not running as expected.");
|
|
75
82
|
}
|
|
76
83
|
}
|
|
77
84
|
|