appwrite-cli 4.2.0 → 4.2.2

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.
@@ -9,422 +9,548 @@ const { Command } = require('commander');
9
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
+ const { File } = require('undici');
13
+ const { ReadableStream } = require('stream/web');
14
+
15
+ /**
16
+ * @param {fs.ReadStream} readStream
17
+ * @returns {ReadableStream}
18
+ */
19
+ function convertReadStreamToReadableStream(readStream) {
20
+ return new ReadableStream({
21
+ start(controller) {
22
+ readStream.on("data", (chunk) => {
23
+ controller.enqueue(chunk);
24
+ });
25
+ readStream.on("end", () => {
26
+ controller.close();
27
+ });
28
+ readStream.on("error", (err) => {
29
+ controller.error(err);
30
+ });
31
+ },
32
+ cancel() {
33
+ readStream.destroy();
34
+ },
35
+ });
36
+ }
12
37
 
13
38
  const storage = new Command("storage").description(commandDescriptions['storage']).configureHelp({
14
39
  helpWidth: process.stdout.columns || 80
15
- })
16
-
40
+ })
41
+
42
+ /**
43
+ * @typedef {Object} StorageListBucketsRequestParams
44
+ * @property {string[]} queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: enabled, name, fileSecurity, maximumFileSize, encryption, antivirus
45
+ * @property {string} search Search term to filter your list results. Max length: 256 chars.
46
+ * @property {boolean} parseOutput
47
+ * @property {libClient | undefined} sdk
48
+ */
49
+
50
+ /**
51
+ * @param {StorageListBucketsRequestParams} params
52
+ */
17
53
  const storageListBuckets = async ({ queries, search, parseOutput = true, sdk = undefined}) => {
18
- /* @param {string[]} queries */
19
- /* @param {string} search */
20
-
21
54
  let client = !sdk ? await sdkForProject() : sdk;
22
55
  let apiPath = '/storage/buckets';
23
56
  let payload = {};
24
-
25
- /** Query Params */
26
57
  if (typeof queries !== 'undefined') {
27
58
  payload['queries'] = queries;
28
59
  }
29
60
  if (typeof search !== 'undefined') {
30
61
  payload['search'] = search;
31
62
  }
63
+
32
64
  let response = undefined;
65
+
33
66
  response = await client.call('get', apiPath, {
34
67
  'content-type': 'application/json',
35
68
  }, payload);
36
-
69
+
37
70
  if (parseOutput) {
38
71
  parse(response)
39
72
  success()
40
73
  }
74
+
41
75
  return response;
42
76
  }
43
77
 
78
+ /**
79
+ * @typedef {Object} StorageCreateBucketRequestParams
80
+ * @property {string} bucketId Unique Id. Choose a custom ID or generate a random ID with 'ID.unique()'. 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.
81
+ * @property {string} name Bucket name
82
+ * @property {string[]} permissions An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
83
+ * @property {boolean} fileSecurity Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions).
84
+ * @property {boolean} enabled Is bucket enabled? When set to 'disabled', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.
85
+ * @property {number} maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 30MB.
86
+ * @property {string[]} allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.
87
+ * @property {string} compression Compression algorithm choosen for compression. Can be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd), For file size above 20MB compression is skipped even if it's enabled
88
+ * @property {boolean} encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled
89
+ * @property {boolean} antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled
90
+ * @property {boolean} parseOutput
91
+ * @property {libClient | undefined} sdk
92
+ */
93
+
94
+ /**
95
+ * @param {StorageCreateBucketRequestParams} params
96
+ */
44
97
  const storageCreateBucket = async ({ bucketId, name, permissions, fileSecurity, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus, parseOutput = true, sdk = undefined}) => {
45
- /* @param {string} bucketId */
46
- /* @param {string} name */
47
- /* @param {string[]} permissions */
48
- /* @param {boolean} fileSecurity */
49
- /* @param {boolean} enabled */
50
- /* @param {number} maximumFileSize */
51
- /* @param {string[]} allowedFileExtensions */
52
- /* @param {string} compression */
53
- /* @param {boolean} encryption */
54
- /* @param {boolean} antivirus */
55
-
56
98
  let client = !sdk ? await sdkForProject() : sdk;
57
99
  let apiPath = '/storage/buckets';
58
100
  let payload = {};
59
-
60
- /** Body Params */
61
-
62
101
  if (typeof bucketId !== 'undefined') {
63
102
  payload['bucketId'] = bucketId;
64
103
  }
65
-
66
-
67
104
  if (typeof name !== 'undefined') {
68
105
  payload['name'] = name;
69
106
  }
70
-
71
107
  permissions = permissions === true ? [] : permissions;
72
-
73
108
  if (typeof permissions !== 'undefined') {
74
109
  payload['permissions'] = permissions;
75
110
  }
76
-
77
-
78
111
  if (typeof fileSecurity !== 'undefined') {
79
112
  payload['fileSecurity'] = fileSecurity;
80
113
  }
81
-
82
-
83
114
  if (typeof enabled !== 'undefined') {
84
115
  payload['enabled'] = enabled;
85
116
  }
86
-
87
-
88
117
  if (typeof maximumFileSize !== 'undefined') {
89
118
  payload['maximumFileSize'] = maximumFileSize;
90
119
  }
91
-
92
120
  allowedFileExtensions = allowedFileExtensions === true ? [] : allowedFileExtensions;
93
-
94
121
  if (typeof allowedFileExtensions !== 'undefined') {
95
122
  payload['allowedFileExtensions'] = allowedFileExtensions;
96
123
  }
97
-
98
-
99
124
  if (typeof compression !== 'undefined') {
100
125
  payload['compression'] = compression;
101
126
  }
102
-
103
-
104
127
  if (typeof encryption !== 'undefined') {
105
128
  payload['encryption'] = encryption;
106
129
  }
107
-
108
-
109
130
  if (typeof antivirus !== 'undefined') {
110
131
  payload['antivirus'] = antivirus;
111
132
  }
112
133
 
113
134
  let response = undefined;
135
+
114
136
  response = await client.call('post', apiPath, {
115
137
  'content-type': 'application/json',
116
138
  }, payload);
117
-
139
+
118
140
  if (parseOutput) {
119
141
  parse(response)
120
142
  success()
121
143
  }
144
+
122
145
  return response;
123
146
  }
124
147
 
125
- const storageGetBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
126
- /* @param {string} bucketId */
148
+ /**
149
+ * @typedef {Object} StorageGetBucketRequestParams
150
+ * @property {string} bucketId Bucket unique ID.
151
+ * @property {boolean} parseOutput
152
+ * @property {libClient | undefined} sdk
153
+ */
127
154
 
155
+ /**
156
+ * @param {StorageGetBucketRequestParams} params
157
+ */
158
+ const storageGetBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
128
159
  let client = !sdk ? await sdkForProject() : sdk;
129
160
  let apiPath = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
130
161
  let payload = {};
162
+
131
163
  let response = undefined;
164
+
132
165
  response = await client.call('get', apiPath, {
133
166
  'content-type': 'application/json',
134
167
  }, payload);
135
-
168
+
136
169
  if (parseOutput) {
137
170
  parse(response)
138
171
  success()
139
172
  }
173
+
140
174
  return response;
141
175
  }
142
176
 
177
+ /**
178
+ * @typedef {Object} StorageUpdateBucketRequestParams
179
+ * @property {string} bucketId Bucket unique ID.
180
+ * @property {string} name Bucket name
181
+ * @property {string[]} permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).
182
+ * @property {boolean} fileSecurity Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions).
183
+ * @property {boolean} enabled Is bucket enabled? When set to 'disabled', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.
184
+ * @property {number} maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 30MB.
185
+ * @property {string[]} allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.
186
+ * @property {string} compression Compression algorithm choosen for compression. Can be one of none, [gzip](https://en.wikipedia.org/wiki/Gzip), or [zstd](https://en.wikipedia.org/wiki/Zstd), For file size above 20MB compression is skipped even if it's enabled
187
+ * @property {boolean} encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled
188
+ * @property {boolean} antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled
189
+ * @property {boolean} parseOutput
190
+ * @property {libClient | undefined} sdk
191
+ */
192
+
193
+ /**
194
+ * @param {StorageUpdateBucketRequestParams} params
195
+ */
143
196
  const storageUpdateBucket = async ({ bucketId, name, permissions, fileSecurity, enabled, maximumFileSize, allowedFileExtensions, compression, encryption, antivirus, parseOutput = true, sdk = undefined}) => {
144
- /* @param {string} bucketId */
145
- /* @param {string} name */
146
- /* @param {string[]} permissions */
147
- /* @param {boolean} fileSecurity */
148
- /* @param {boolean} enabled */
149
- /* @param {number} maximumFileSize */
150
- /* @param {string[]} allowedFileExtensions */
151
- /* @param {string} compression */
152
- /* @param {boolean} encryption */
153
- /* @param {boolean} antivirus */
154
-
155
197
  let client = !sdk ? await sdkForProject() : sdk;
156
198
  let apiPath = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
157
199
  let payload = {};
158
-
159
- /** Body Params */
160
-
161
200
  if (typeof name !== 'undefined') {
162
201
  payload['name'] = name;
163
202
  }
164
-
165
203
  permissions = permissions === true ? [] : permissions;
166
-
167
204
  if (typeof permissions !== 'undefined') {
168
205
  payload['permissions'] = permissions;
169
206
  }
170
-
171
-
172
207
  if (typeof fileSecurity !== 'undefined') {
173
208
  payload['fileSecurity'] = fileSecurity;
174
209
  }
175
-
176
-
177
210
  if (typeof enabled !== 'undefined') {
178
211
  payload['enabled'] = enabled;
179
212
  }
180
-
181
-
182
213
  if (typeof maximumFileSize !== 'undefined') {
183
214
  payload['maximumFileSize'] = maximumFileSize;
184
215
  }
185
-
186
216
  allowedFileExtensions = allowedFileExtensions === true ? [] : allowedFileExtensions;
187
-
188
217
  if (typeof allowedFileExtensions !== 'undefined') {
189
218
  payload['allowedFileExtensions'] = allowedFileExtensions;
190
219
  }
191
-
192
-
193
220
  if (typeof compression !== 'undefined') {
194
221
  payload['compression'] = compression;
195
222
  }
196
-
197
-
198
223
  if (typeof encryption !== 'undefined') {
199
224
  payload['encryption'] = encryption;
200
225
  }
201
-
202
-
203
226
  if (typeof antivirus !== 'undefined') {
204
227
  payload['antivirus'] = antivirus;
205
228
  }
206
229
 
207
230
  let response = undefined;
231
+
208
232
  response = await client.call('put', apiPath, {
209
233
  'content-type': 'application/json',
210
234
  }, payload);
211
-
235
+
212
236
  if (parseOutput) {
213
237
  parse(response)
214
238
  success()
215
239
  }
240
+
216
241
  return response;
217
242
  }
218
243
 
219
- const storageDeleteBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
220
- /* @param {string} bucketId */
244
+ /**
245
+ * @typedef {Object} StorageDeleteBucketRequestParams
246
+ * @property {string} bucketId Bucket unique ID.
247
+ * @property {boolean} parseOutput
248
+ * @property {libClient | undefined} sdk
249
+ */
221
250
 
251
+ /**
252
+ * @param {StorageDeleteBucketRequestParams} params
253
+ */
254
+ const storageDeleteBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
222
255
  let client = !sdk ? await sdkForProject() : sdk;
223
256
  let apiPath = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
224
257
  let payload = {};
258
+
225
259
  let response = undefined;
260
+
226
261
  response = await client.call('delete', apiPath, {
227
262
  'content-type': 'application/json',
228
263
  }, payload);
229
-
264
+
230
265
  if (parseOutput) {
231
266
  parse(response)
232
267
  success()
233
268
  }
269
+
234
270
  return response;
235
271
  }
236
272
 
273
+ /**
274
+ * @typedef {Object} StorageListFilesRequestParams
275
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
276
+ * @property {string[]} queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, signature, mimeType, sizeOriginal, chunksTotal, chunksUploaded
277
+ * @property {string} search Search term to filter your list results. Max length: 256 chars.
278
+ * @property {boolean} parseOutput
279
+ * @property {libClient | undefined} sdk
280
+ */
281
+
282
+ /**
283
+ * @param {StorageListFilesRequestParams} params
284
+ */
237
285
  const storageListFiles = async ({ bucketId, queries, search, parseOutput = true, sdk = undefined}) => {
238
- /* @param {string} bucketId */
239
- /* @param {string[]} queries */
240
- /* @param {string} search */
241
-
242
286
  let client = !sdk ? await sdkForProject() : sdk;
243
287
  let apiPath = '/storage/buckets/{bucketId}/files'.replace('{bucketId}', bucketId);
244
288
  let payload = {};
245
-
246
- /** Query Params */
247
289
  if (typeof queries !== 'undefined') {
248
290
  payload['queries'] = queries;
249
291
  }
250
292
  if (typeof search !== 'undefined') {
251
293
  payload['search'] = search;
252
294
  }
295
+
253
296
  let response = undefined;
297
+
254
298
  response = await client.call('get', apiPath, {
255
299
  'content-type': 'application/json',
256
300
  }, payload);
257
-
301
+
258
302
  if (parseOutput) {
259
303
  parse(response)
260
304
  success()
261
305
  }
306
+
262
307
  return response;
263
308
  }
264
309
 
310
+ /**
311
+ * @typedef {Object} StorageCreateFileRequestParams
312
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
313
+ * @property {string} fileId File ID. Choose a custom ID or generate a random ID with 'ID.unique()'. 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.
314
+ * @property {string} file Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/storage#file-input).
315
+ * @property {string[]} permissions An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
316
+ * @property {boolean} parseOutput
317
+ * @property {libClient | undefined} sdk
318
+ * @property {CallableFunction} onProgress
319
+ */
320
+
321
+ /**
322
+ * @param {StorageCreateFileRequestParams} params
323
+ */
265
324
  const storageCreateFile = async ({ bucketId, fileId, file, permissions, parseOutput = true, sdk = undefined, onProgress = () => {}}) => {
266
- /* @param {string} bucketId */
267
- /* @param {string} fileId */
268
- /* @param {InputFile} file */
269
- /* @param {string[]} permissions */
270
-
271
325
  let client = !sdk ? await sdkForProject() : sdk;
272
326
  let apiPath = '/storage/buckets/{bucketId}/files'.replace('{bucketId}', bucketId);
273
327
  let payload = {};
274
-
275
- /** Body Params */
276
-
277
328
  if (typeof fileId !== 'undefined') {
278
329
  payload['fileId'] = fileId;
279
330
  }
331
+ const filePath = fs.realpathSync(file);
332
+ const nodeStream = fs.createReadStream(filePath);
333
+ const stream = convertReadStreamToReadableStream(nodeStream);
280
334
 
281
- let filePath = fs.realpathSync(file);
282
335
  if (typeof filePath !== 'undefined') {
283
- payload['file'] = filePath;
336
+ file = { type: 'file', stream, filename: pathLib.basename(filePath), size: fs.statSync(filePath).size };
337
+ payload['file'] = file
284
338
  }
285
-
286
339
  permissions = permissions === true ? [] : permissions;
287
-
288
340
  if (typeof permissions !== 'undefined') {
289
341
  payload['permissions'] = permissions;
290
342
  }
291
343
 
344
+ const size = file.size;
345
+
346
+ const apiHeaders = {
347
+ 'content-type': 'multipart/form-data',
348
+ };
349
+
350
+ let id = undefined;
292
351
  let response = undefined;
293
- const { size: size } = await promisify(fs.stat)(file);
294
-
295
- if (size <= libClient.CHUNK_SIZE) {
296
- payload['file'] = fs.createReadStream(payload['file']);
297
-
298
- response = await client.call('post', apiPath, {
299
- 'content-type': 'multipart/form-data',
300
- }, payload)
301
- } else {
302
- const streamFilePath = payload['file'];
303
-
304
- const apiHeaders = {
305
- 'content-type': 'multipart/form-data',
306
- };
307
-
308
- let offset = 0;
309
- if(fileId != 'unique()') {
310
- try {
311
- response = await client.call('get', apiPath + '/' + fileId, apiHeaders);
312
- offset = response.chunksUploaded * libClient.CHUNK_SIZE;
313
- } catch(e) {
314
- }
352
+
353
+ let chunksUploaded = 0;
354
+
355
+ if(fileId != 'unique()') {
356
+ try {
357
+ response = await client.call('get', apiPath + '/' + fileId, apiHeaders);
358
+ chunksUploaded = response.chunksUploaded;
359
+ } catch(e) {
360
+ }
361
+ }
362
+
363
+ let currentChunk = 1;
364
+ let currentPosition = 0;
365
+ let uploadableChunk = new Uint8Array(client.CHUNK_SIZE);
366
+
367
+ const uploadChunk = async (lastUpload = false) => {
368
+ if(currentChunk <= chunksUploaded) {
369
+ return;
315
370
  }
316
371
 
317
- while (offset < size) {
318
- let end = Math.min(offset + libClient.CHUNK_SIZE - 1, size - 1);
372
+ const start = ((currentChunk - 1) * client.CHUNK_SIZE);
373
+ let end = start + currentPosition - 1;
319
374
 
320
- apiHeaders['content-range'] = 'bytes ' + offset + '-' + end + '/' + size;
321
- if (response && response.$id) {
322
- apiHeaders['x-appwrite-id'] = response.$id;
375
+ if(!lastUpload || currentChunk !== 1) {
376
+ apiHeaders['content-range'] = 'bytes ' + start + '-' + end + '/' + size;
377
+ }
378
+
379
+ let uploadableChunkTrimmed;
380
+
381
+ if(currentPosition + 1 >= client.CHUNK_SIZE) {
382
+ uploadableChunkTrimmed = uploadableChunk;
383
+ } else {
384
+ uploadableChunkTrimmed = new Uint8Array(currentPosition);
385
+ for(let i = 0; i <= currentPosition; i++) {
386
+ uploadableChunkTrimmed[i] = uploadableChunk[i];
323
387
  }
388
+ }
389
+
390
+ if (id) {
391
+ apiHeaders['x-appwrite-id'] = id;
392
+ }
393
+
394
+ payload['file'] = { type: 'file', file: new File([uploadableChunkTrimmed], file.filename), filename: file.filename };
324
395
 
325
- const stream = fs.createReadStream(streamFilePath, {
326
- start: offset,
327
- end
396
+ response = await client.call('post', apiPath, apiHeaders, payload);
397
+
398
+ if (!id) {
399
+ id = response['$id'];
400
+ }
401
+
402
+ if (onProgress !== null) {
403
+ onProgress({
404
+ $id: response['$id'],
405
+ progress: Math.min((currentChunk) * client.CHUNK_SIZE, size) / size * 100,
406
+ sizeUploaded: end+1,
407
+ chunksTotal: response['chunksTotal'],
408
+ chunksUploaded: response['chunksUploaded']
328
409
  });
329
- payload['file'] = stream;
330
- response = await client.call('post', apiPath, apiHeaders, payload);
331
-
332
- if (onProgress) {
333
- onProgress({
334
- $id: response.$id,
335
- progress: ( offset / size ) * 100,
336
- sizeUploaded: offset,
337
- chunksTotal: response.chunksTotal,
338
- chunksUploaded: response.chunksUploaded
339
- });
410
+ }
411
+
412
+ uploadableChunk = new Uint8Array(client.CHUNK_SIZE);
413
+ currentChunk++;
414
+ currentPosition = 0;
415
+ }
416
+
417
+ for await (const chunk of file.stream) {
418
+ for(const b of chunk) {
419
+ uploadableChunk[currentPosition] = b;
420
+
421
+ currentPosition++;
422
+ if(currentPosition >= client.CHUNK_SIZE) {
423
+ await uploadChunk();
424
+ currentPosition = 0;
340
425
  }
341
- offset += libClient.CHUNK_SIZE;
342
426
  }
343
427
  }
344
-
428
+
429
+ if (currentPosition > 0) { // Check if there's any remaining data for the last chunk
430
+ await uploadChunk(true);
431
+ }
432
+
433
+
345
434
  if (parseOutput) {
346
435
  parse(response)
347
436
  success()
348
437
  }
438
+
349
439
  return response;
350
440
  }
351
441
 
442
+ /**
443
+ * @typedef {Object} StorageGetFileRequestParams
444
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
445
+ * @property {string} fileId File ID.
446
+ * @property {boolean} parseOutput
447
+ * @property {libClient | undefined} sdk
448
+ */
449
+
450
+ /**
451
+ * @param {StorageGetFileRequestParams} params
452
+ */
352
453
  const storageGetFile = async ({ bucketId, fileId, parseOutput = true, sdk = undefined}) => {
353
- /* @param {string} bucketId */
354
- /* @param {string} fileId */
355
-
356
454
  let client = !sdk ? await sdkForProject() : sdk;
357
455
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
358
456
  let payload = {};
457
+
359
458
  let response = undefined;
459
+
360
460
  response = await client.call('get', apiPath, {
361
461
  'content-type': 'application/json',
362
462
  }, payload);
363
-
463
+
364
464
  if (parseOutput) {
365
465
  parse(response)
366
466
  success()
367
467
  }
468
+
368
469
  return response;
369
470
  }
370
471
 
472
+ /**
473
+ * @typedef {Object} StorageUpdateFileRequestParams
474
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
475
+ * @property {string} fileId File unique ID.
476
+ * @property {string} name Name of the file
477
+ * @property {string[]} permissions An array of permission string. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).
478
+ * @property {boolean} parseOutput
479
+ * @property {libClient | undefined} sdk
480
+ */
481
+
482
+ /**
483
+ * @param {StorageUpdateFileRequestParams} params
484
+ */
371
485
  const storageUpdateFile = async ({ bucketId, fileId, name, permissions, parseOutput = true, sdk = undefined}) => {
372
- /* @param {string} bucketId */
373
- /* @param {string} fileId */
374
- /* @param {string} name */
375
- /* @param {string[]} permissions */
376
-
377
486
  let client = !sdk ? await sdkForProject() : sdk;
378
487
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
379
488
  let payload = {};
380
-
381
- /** Body Params */
382
-
383
489
  if (typeof name !== 'undefined') {
384
490
  payload['name'] = name;
385
491
  }
386
-
387
492
  permissions = permissions === true ? [] : permissions;
388
-
389
493
  if (typeof permissions !== 'undefined') {
390
494
  payload['permissions'] = permissions;
391
495
  }
392
496
 
393
497
  let response = undefined;
498
+
394
499
  response = await client.call('put', apiPath, {
395
500
  'content-type': 'application/json',
396
501
  }, payload);
397
-
502
+
398
503
  if (parseOutput) {
399
504
  parse(response)
400
505
  success()
401
506
  }
507
+
402
508
  return response;
403
509
  }
404
510
 
511
+ /**
512
+ * @typedef {Object} StorageDeleteFileRequestParams
513
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
514
+ * @property {string} fileId File ID.
515
+ * @property {boolean} parseOutput
516
+ * @property {libClient | undefined} sdk
517
+ */
518
+
519
+ /**
520
+ * @param {StorageDeleteFileRequestParams} params
521
+ */
405
522
  const storageDeleteFile = async ({ bucketId, fileId, parseOutput = true, sdk = undefined}) => {
406
- /* @param {string} bucketId */
407
- /* @param {string} fileId */
408
-
409
523
  let client = !sdk ? await sdkForProject() : sdk;
410
524
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
411
525
  let payload = {};
526
+
412
527
  let response = undefined;
528
+
413
529
  response = await client.call('delete', apiPath, {
414
530
  'content-type': 'application/json',
415
531
  }, payload);
416
-
532
+
417
533
  if (parseOutput) {
418
534
  parse(response)
419
535
  success()
420
536
  }
537
+
421
538
  return response;
422
539
  }
423
540
 
541
+ /**
542
+ * @typedef {Object} StorageGetFileDownloadRequestParams
543
+ * @property {string} bucketId Storage bucket ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
544
+ * @property {string} fileId File ID.
545
+ * @property {boolean} parseOutput
546
+ * @property {libClient | undefined} sdk
547
+ * @property {string} destination
548
+ */
549
+
550
+ /**
551
+ * @param {StorageGetFileDownloadRequestParams} params
552
+ */
424
553
  const storageGetFileDownload = async ({ bucketId, fileId, parseOutput = true, sdk = undefined, destination}) => {
425
- /* @param {string} bucketId */
426
- /* @param {string} fileId */
427
-
428
554
  let client = !sdk ? await sdkForProject() : sdk;
429
555
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}/download'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
430
556
  let payload = {};
@@ -433,38 +559,49 @@ const storageGetFileDownload = async ({ bucketId, fileId, parseOutput = true, sd
433
559
  const queryParams = new URLSearchParams(payload);
434
560
  apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
435
561
 
436
- const response = await client.call('get', apiPath, {
562
+ let response = undefined;
563
+
564
+ response = await client.call('get', apiPath, {
437
565
  'content-type': 'application/json',
438
566
  }, payload, 'arraybuffer');
439
567
 
440
568
  fs.writeFileSync(destination, response);
441
569
 
442
- if (parseOutput) {
443
- log(`File stored in ${destination}`)
570
+ if (parseOutput) {
571
+ parse(response)
444
572
  success()
445
573
  }
574
+
575
+ return response;
446
576
  }
447
577
 
578
+ /**
579
+ * @typedef {Object} StorageGetFilePreviewRequestParams
580
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
581
+ * @property {string} fileId File ID
582
+ * @property {number} width Resize preview image width, Pass an integer between 0 to 4000.
583
+ * @property {number} height Resize preview image height, Pass an integer between 0 to 4000.
584
+ * @property {string} gravity Image crop gravity. Can be one of center,top-left,top,top-right,left,right,bottom-left,bottom,bottom-right
585
+ * @property {number} quality Preview image quality. Pass an integer between 0 to 100. Defaults to 100.
586
+ * @property {number} borderWidth Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0.
587
+ * @property {string} borderColor Preview image border color. Use a valid HEX color, no # is needed for prefix.
588
+ * @property {number} borderRadius Preview image border radius in pixels. Pass an integer between 0 to 4000.
589
+ * @property {number} opacity Preview image opacity. Only works with images having an alpha channel (like png). Pass a number between 0 to 1.
590
+ * @property {number} rotation Preview image rotation in degrees. Pass an integer between -360 and 360.
591
+ * @property {string} background Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.
592
+ * @property {string} output Output format type (jpeg, jpg, png, gif and webp).
593
+ * @property {boolean} parseOutput
594
+ * @property {libClient | undefined} sdk
595
+ * @property {string} destination
596
+ */
597
+
598
+ /**
599
+ * @param {StorageGetFilePreviewRequestParams} params
600
+ */
448
601
  const storageGetFilePreview = async ({ bucketId, fileId, width, height, gravity, quality, borderWidth, borderColor, borderRadius, opacity, rotation, background, output, parseOutput = true, sdk = undefined, destination}) => {
449
- /* @param {string} bucketId */
450
- /* @param {string} fileId */
451
- /* @param {number} width */
452
- /* @param {number} height */
453
- /* @param {string} gravity */
454
- /* @param {number} quality */
455
- /* @param {number} borderWidth */
456
- /* @param {string} borderColor */
457
- /* @param {number} borderRadius */
458
- /* @param {number} opacity */
459
- /* @param {number} rotation */
460
- /* @param {string} background */
461
- /* @param {string} output */
462
-
463
602
  let client = !sdk ? await sdkForProject() : sdk;
464
603
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}/preview'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
465
604
  let payload = {};
466
-
467
- /** Query Params */
468
605
  if (typeof width !== 'undefined') {
469
606
  payload['width'] = width;
470
607
  }
@@ -503,22 +640,35 @@ const storageGetFilePreview = async ({ bucketId, fileId, width, height, gravity,
503
640
  const queryParams = new URLSearchParams(payload);
504
641
  apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
505
642
 
506
- const response = await client.call('get', apiPath, {
643
+ let response = undefined;
644
+
645
+ response = await client.call('get', apiPath, {
507
646
  'content-type': 'application/json',
508
647
  }, payload, 'arraybuffer');
509
648
 
510
649
  fs.writeFileSync(destination, response);
511
650
 
512
- if (parseOutput) {
513
- log(`File stored in ${destination}`)
651
+ if (parseOutput) {
652
+ parse(response)
514
653
  success()
515
654
  }
655
+
656
+ return response;
516
657
  }
517
658
 
659
+ /**
660
+ * @typedef {Object} StorageGetFileViewRequestParams
661
+ * @property {string} bucketId Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).
662
+ * @property {string} fileId File ID.
663
+ * @property {boolean} parseOutput
664
+ * @property {libClient | undefined} sdk
665
+ * @property {string} destination
666
+ */
667
+
668
+ /**
669
+ * @param {StorageGetFileViewRequestParams} params
670
+ */
518
671
  const storageGetFileView = async ({ bucketId, fileId, parseOutput = true, sdk = undefined, destination}) => {
519
- /* @param {string} bucketId */
520
- /* @param {string} fileId */
521
-
522
672
  let client = !sdk ? await sdkForProject() : sdk;
523
673
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}/view'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
524
674
  let payload = {};
@@ -527,66 +677,87 @@ const storageGetFileView = async ({ bucketId, fileId, parseOutput = true, sdk =
527
677
  const queryParams = new URLSearchParams(payload);
528
678
  apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
529
679
 
530
- const response = await client.call('get', apiPath, {
680
+ let response = undefined;
681
+
682
+ response = await client.call('get', apiPath, {
531
683
  'content-type': 'application/json',
532
684
  }, payload, 'arraybuffer');
533
685
 
534
686
  fs.writeFileSync(destination, response);
535
687
 
536
- if (parseOutput) {
537
- log(`File stored in ${destination}`)
688
+ if (parseOutput) {
689
+ parse(response)
538
690
  success()
539
691
  }
692
+
693
+ return response;
540
694
  }
541
695
 
542
- const storageGetUsage = async ({ range, parseOutput = true, sdk = undefined}) => {
543
- /* @param {string} range */
696
+ /**
697
+ * @typedef {Object} StorageGetUsageRequestParams
698
+ * @property {string} range Date range.
699
+ * @property {boolean} parseOutput
700
+ * @property {libClient | undefined} sdk
701
+ */
544
702
 
703
+ /**
704
+ * @param {StorageGetUsageRequestParams} params
705
+ */
706
+ const storageGetUsage = async ({ range, parseOutput = true, sdk = undefined}) => {
545
707
  let client = !sdk ? await sdkForProject() : sdk;
546
708
  let apiPath = '/storage/usage';
547
709
  let payload = {};
548
-
549
- /** Query Params */
550
710
  if (typeof range !== 'undefined') {
551
711
  payload['range'] = range;
552
712
  }
713
+
553
714
  let response = undefined;
715
+
554
716
  response = await client.call('get', apiPath, {
555
717
  'content-type': 'application/json',
556
718
  }, payload);
557
-
719
+
558
720
  if (parseOutput) {
559
721
  parse(response)
560
722
  success()
561
723
  }
724
+
562
725
  return response;
563
726
  }
564
727
 
728
+ /**
729
+ * @typedef {Object} StorageGetBucketUsageRequestParams
730
+ * @property {string} bucketId Bucket ID.
731
+ * @property {string} range Date range.
732
+ * @property {boolean} parseOutput
733
+ * @property {libClient | undefined} sdk
734
+ */
735
+
736
+ /**
737
+ * @param {StorageGetBucketUsageRequestParams} params
738
+ */
565
739
  const storageGetBucketUsage = async ({ bucketId, range, parseOutput = true, sdk = undefined}) => {
566
- /* @param {string} bucketId */
567
- /* @param {string} range */
568
-
569
740
  let client = !sdk ? await sdkForProject() : sdk;
570
741
  let apiPath = '/storage/{bucketId}/usage'.replace('{bucketId}', bucketId);
571
742
  let payload = {};
572
-
573
- /** Query Params */
574
743
  if (typeof range !== 'undefined') {
575
744
  payload['range'] = range;
576
745
  }
746
+
577
747
  let response = undefined;
748
+
578
749
  response = await client.call('get', apiPath, {
579
750
  'content-type': 'application/json',
580
751
  }, payload);
581
-
752
+
582
753
  if (parseOutput) {
583
754
  parse(response)
584
755
  success()
585
756
  }
757
+
586
758
  return response;
587
759
  }
588
760
 
589
-
590
761
  storage
591
762
  .command(`listBuckets`)
592
763
  .description(`Get a list of all the storage buckets. You can use the query params to filter your results.`)
@@ -724,7 +895,6 @@ storage
724
895
  .option(`--range <range>`, `Date range.`)
725
896
  .action(actionRunner(storageGetBucketUsage))
726
897
 
727
-
728
898
  module.exports = {
729
899
  storage,
730
900
  storageListBuckets,
@@ -742,4 +912,4 @@ module.exports = {
742
912
  storageGetFileView,
743
913
  storageGetUsage,
744
914
  storageGetBucketUsage
745
- };
915
+ };