appwrite-cli 4.1.0 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +3 -3
  3. package/docs/examples/health/get-queue-builds.md +2 -0
  4. package/docs/examples/health/get-queue-certificates.md +2 -1
  5. package/docs/examples/health/get-queue-databases.md +3 -0
  6. package/docs/examples/health/get-queue-deletes.md +2 -0
  7. package/docs/examples/health/get-queue-functions.md +2 -1
  8. package/docs/examples/health/get-queue-logs.md +2 -1
  9. package/docs/examples/health/get-queue-mails.md +2 -0
  10. package/docs/examples/health/get-queue-messaging.md +2 -0
  11. package/docs/examples/health/get-queue-migrations.md +2 -0
  12. package/docs/examples/health/get-queue-webhooks.md +2 -1
  13. package/install.ps1 +2 -2
  14. package/install.sh +1 -1
  15. package/lib/client.js +61 -74
  16. package/lib/commands/account.js +564 -210
  17. package/lib/commands/assistant.js +42 -7
  18. package/lib/commands/avatars.js +199 -83
  19. package/lib/commands/console.js +42 -3
  20. package/lib/commands/databases.js +991 -562
  21. package/lib/commands/deploy.js +170 -99
  22. package/lib/commands/functions.js +564 -294
  23. package/lib/commands/graphql.js +58 -11
  24. package/lib/commands/health.js +496 -26
  25. package/lib/commands/init.js +11 -23
  26. package/lib/commands/locale.js +154 -17
  27. package/lib/commands/migrations.js +328 -147
  28. package/lib/commands/project.js +128 -33
  29. package/lib/commands/projects.js +788 -411
  30. package/lib/commands/proxy.js +113 -28
  31. package/lib/commands/storage.js +438 -223
  32. package/lib/commands/teams.js +284 -108
  33. package/lib/commands/users.js +559 -271
  34. package/lib/commands/vcs.js +186 -53
  35. package/lib/paginate.js +51 -0
  36. package/lib/questions.js +7 -10
  37. package/package.json +9 -9
  38. package/scoop/appwrite.json +3 -3
@@ -9,462 +9,633 @@ 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
40
  })
16
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;
55
+
22
56
  let apiPath = '/storage/buckets';
23
57
  let payload = {};
24
-
25
- /** Query Params */
26
58
  if (typeof queries !== 'undefined') {
27
59
  payload['queries'] = queries;
28
60
  }
29
61
  if (typeof search !== 'undefined') {
30
62
  payload['search'] = search;
31
63
  }
64
+
65
+
32
66
  let response = undefined;
67
+
33
68
  response = await client.call('get', apiPath, {
34
69
  'content-type': 'application/json',
35
70
  }, payload);
71
+
36
72
 
37
73
  if (parseOutput) {
38
74
  parse(response)
39
75
  success()
40
76
  }
77
+
41
78
  return response;
42
79
  }
43
80
 
81
+ /**
82
+ * @typedef {Object} StorageCreateBucketRequestParams
83
+ * @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.
84
+ * @property {string} name Bucket name
85
+ * @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).
86
+ * @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).
87
+ * @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.
88
+ * @property {number} maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 30MB.
89
+ * @property {string[]} allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.
90
+ * @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
91
+ * @property {boolean} encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled
92
+ * @property {boolean} antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled
93
+ * @property {boolean} parseOutput
94
+ * @property {libClient | undefined} sdk
95
+ */
96
+
97
+ /**
98
+ * @param {StorageCreateBucketRequestParams} params
99
+ */
44
100
  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
101
  let client = !sdk ? await sdkForProject() : sdk;
102
+
57
103
  let apiPath = '/storage/buckets';
58
104
  let payload = {};
59
-
60
- /** Body Params */
61
-
62
105
  if (typeof bucketId !== 'undefined') {
63
106
  payload['bucketId'] = bucketId;
64
107
  }
65
-
66
-
67
108
  if (typeof name !== 'undefined') {
68
109
  payload['name'] = name;
69
110
  }
70
-
71
111
  permissions = permissions === true ? [] : permissions;
72
-
73
112
  if (typeof permissions !== 'undefined') {
74
113
  payload['permissions'] = permissions;
75
114
  }
76
-
77
-
78
115
  if (typeof fileSecurity !== 'undefined') {
79
116
  payload['fileSecurity'] = fileSecurity;
80
117
  }
81
-
82
-
83
118
  if (typeof enabled !== 'undefined') {
84
119
  payload['enabled'] = enabled;
85
120
  }
86
-
87
-
88
121
  if (typeof maximumFileSize !== 'undefined') {
89
122
  payload['maximumFileSize'] = maximumFileSize;
90
123
  }
91
-
92
124
  allowedFileExtensions = allowedFileExtensions === true ? [] : allowedFileExtensions;
93
-
94
125
  if (typeof allowedFileExtensions !== 'undefined') {
95
126
  payload['allowedFileExtensions'] = allowedFileExtensions;
96
127
  }
97
-
98
-
99
128
  if (typeof compression !== 'undefined') {
100
129
  payload['compression'] = compression;
101
130
  }
102
-
103
-
104
131
  if (typeof encryption !== 'undefined') {
105
132
  payload['encryption'] = encryption;
106
133
  }
107
-
108
-
109
134
  if (typeof antivirus !== 'undefined') {
110
135
  payload['antivirus'] = antivirus;
111
136
  }
112
137
 
138
+
113
139
  let response = undefined;
140
+
114
141
  response = await client.call('post', apiPath, {
115
142
  'content-type': 'application/json',
116
143
  }, payload);
144
+
117
145
 
118
146
  if (parseOutput) {
119
147
  parse(response)
120
148
  success()
121
149
  }
150
+
122
151
  return response;
123
152
  }
124
153
 
125
- const storageGetBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
126
- /* @param {string} bucketId */
154
+ /**
155
+ * @typedef {Object} StorageGetBucketRequestParams
156
+ * @property {string} bucketId Bucket unique ID.
157
+ * @property {boolean} parseOutput
158
+ * @property {libClient | undefined} sdk
159
+ */
127
160
 
161
+ /**
162
+ * @param {StorageGetBucketRequestParams} params
163
+ */
164
+ const storageGetBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
128
165
  let client = !sdk ? await sdkForProject() : sdk;
166
+
129
167
  let apiPath = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
130
168
  let payload = {};
169
+
170
+
131
171
  let response = undefined;
172
+
132
173
  response = await client.call('get', apiPath, {
133
174
  'content-type': 'application/json',
134
175
  }, payload);
176
+
135
177
 
136
178
  if (parseOutput) {
137
179
  parse(response)
138
180
  success()
139
181
  }
182
+
140
183
  return response;
141
184
  }
142
185
 
186
+ /**
187
+ * @typedef {Object} StorageUpdateBucketRequestParams
188
+ * @property {string} bucketId Bucket unique ID.
189
+ * @property {string} name Bucket name
190
+ * @property {string[]} permissions An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).
191
+ * @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).
192
+ * @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.
193
+ * @property {number} maximumFileSize Maximum file size allowed in bytes. Maximum allowed value is 30MB.
194
+ * @property {string[]} allowedFileExtensions Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.
195
+ * @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
196
+ * @property {boolean} encryption Is encryption enabled? For file size above 20MB encryption is skipped even if it's enabled
197
+ * @property {boolean} antivirus Is virus scanning enabled? For file size above 20MB AntiVirus scanning is skipped even if it's enabled
198
+ * @property {boolean} parseOutput
199
+ * @property {libClient | undefined} sdk
200
+ */
201
+
202
+ /**
203
+ * @param {StorageUpdateBucketRequestParams} params
204
+ */
143
205
  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
206
  let client = !sdk ? await sdkForProject() : sdk;
207
+
156
208
  let apiPath = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
157
209
  let payload = {};
158
-
159
- /** Body Params */
160
-
161
210
  if (typeof name !== 'undefined') {
162
211
  payload['name'] = name;
163
212
  }
164
-
165
213
  permissions = permissions === true ? [] : permissions;
166
-
167
214
  if (typeof permissions !== 'undefined') {
168
215
  payload['permissions'] = permissions;
169
216
  }
170
-
171
-
172
217
  if (typeof fileSecurity !== 'undefined') {
173
218
  payload['fileSecurity'] = fileSecurity;
174
219
  }
175
-
176
-
177
220
  if (typeof enabled !== 'undefined') {
178
221
  payload['enabled'] = enabled;
179
222
  }
180
-
181
-
182
223
  if (typeof maximumFileSize !== 'undefined') {
183
224
  payload['maximumFileSize'] = maximumFileSize;
184
225
  }
185
-
186
226
  allowedFileExtensions = allowedFileExtensions === true ? [] : allowedFileExtensions;
187
-
188
227
  if (typeof allowedFileExtensions !== 'undefined') {
189
228
  payload['allowedFileExtensions'] = allowedFileExtensions;
190
229
  }
191
-
192
-
193
230
  if (typeof compression !== 'undefined') {
194
231
  payload['compression'] = compression;
195
232
  }
196
-
197
-
198
233
  if (typeof encryption !== 'undefined') {
199
234
  payload['encryption'] = encryption;
200
235
  }
201
-
202
-
203
236
  if (typeof antivirus !== 'undefined') {
204
237
  payload['antivirus'] = antivirus;
205
238
  }
206
239
 
240
+
207
241
  let response = undefined;
242
+
208
243
  response = await client.call('put', apiPath, {
209
244
  'content-type': 'application/json',
210
245
  }, payload);
246
+
211
247
 
212
248
  if (parseOutput) {
213
249
  parse(response)
214
250
  success()
215
251
  }
252
+
216
253
  return response;
217
254
  }
218
255
 
219
- const storageDeleteBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
220
- /* @param {string} bucketId */
256
+ /**
257
+ * @typedef {Object} StorageDeleteBucketRequestParams
258
+ * @property {string} bucketId Bucket unique ID.
259
+ * @property {boolean} parseOutput
260
+ * @property {libClient | undefined} sdk
261
+ */
221
262
 
263
+ /**
264
+ * @param {StorageDeleteBucketRequestParams} params
265
+ */
266
+ const storageDeleteBucket = async ({ bucketId, parseOutput = true, sdk = undefined}) => {
222
267
  let client = !sdk ? await sdkForProject() : sdk;
268
+
223
269
  let apiPath = '/storage/buckets/{bucketId}'.replace('{bucketId}', bucketId);
224
270
  let payload = {};
271
+
272
+
225
273
  let response = undefined;
274
+
226
275
  response = await client.call('delete', apiPath, {
227
276
  'content-type': 'application/json',
228
277
  }, payload);
278
+
229
279
 
230
280
  if (parseOutput) {
231
281
  parse(response)
232
282
  success()
233
283
  }
284
+
234
285
  return response;
235
286
  }
236
287
 
288
+ /**
289
+ * @typedef {Object} StorageListFilesRequestParams
290
+ * @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).
291
+ * @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
292
+ * @property {string} search Search term to filter your list results. Max length: 256 chars.
293
+ * @property {boolean} parseOutput
294
+ * @property {libClient | undefined} sdk
295
+ */
296
+
297
+ /**
298
+ * @param {StorageListFilesRequestParams} params
299
+ */
237
300
  const storageListFiles = async ({ bucketId, queries, search, parseOutput = true, sdk = undefined}) => {
238
- /* @param {string} bucketId */
239
- /* @param {string[]} queries */
240
- /* @param {string} search */
241
-
242
301
  let client = !sdk ? await sdkForProject() : sdk;
302
+
243
303
  let apiPath = '/storage/buckets/{bucketId}/files'.replace('{bucketId}', bucketId);
244
304
  let payload = {};
245
-
246
- /** Query Params */
247
305
  if (typeof queries !== 'undefined') {
248
306
  payload['queries'] = queries;
249
307
  }
250
308
  if (typeof search !== 'undefined') {
251
309
  payload['search'] = search;
252
310
  }
311
+
312
+
253
313
  let response = undefined;
314
+
254
315
  response = await client.call('get', apiPath, {
255
316
  'content-type': 'application/json',
256
317
  }, payload);
318
+
257
319
 
258
320
  if (parseOutput) {
259
321
  parse(response)
260
322
  success()
261
323
  }
324
+
262
325
  return response;
263
326
  }
264
327
 
328
+ /**
329
+ * @typedef {Object} StorageCreateFileRequestParams
330
+ * @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).
331
+ * @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.
332
+ * @property {string} file Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/storage#file-input).
333
+ * @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).
334
+ * @property {boolean} parseOutput
335
+ * @property {libClient | undefined} sdk
336
+ * @property {CallableFunction} onProgress
337
+ */
338
+
339
+ /**
340
+ * @param {StorageCreateFileRequestParams} params
341
+ */
265
342
  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
343
  let client = !sdk ? await sdkForProject() : sdk;
344
+
272
345
  let apiPath = '/storage/buckets/{bucketId}/files'.replace('{bucketId}', bucketId);
273
346
  let payload = {};
274
-
275
- /** Body Params */
276
-
277
347
  if (typeof fileId !== 'undefined') {
278
348
  payload['fileId'] = fileId;
279
349
  }
350
+ const filePath = fs.realpathSync(file);
351
+ const nodeStream = fs.createReadStream(filePath);
352
+ const stream = convertReadStreamToReadableStream(nodeStream);
280
353
 
281
- let filePath = fs.realpathSync(file);
282
354
  if (typeof filePath !== 'undefined') {
283
- payload['file'] = filePath;
355
+ file = { type: 'file', stream, filename: pathLib.basename(filePath), size: fs.statSync(filePath).size };
356
+ payload['file'] = file
284
357
  }
285
-
286
358
  permissions = permissions === true ? [] : permissions;
287
-
288
359
  if (typeof permissions !== 'undefined') {
289
360
  payload['permissions'] = permissions;
290
361
  }
291
362
 
363
+
364
+
365
+ const size = file.size;
366
+
367
+ const apiHeaders = {
368
+ 'content-type': 'multipart/form-data',
369
+ };
370
+
371
+ let id = undefined;
292
372
  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
- }
373
+
374
+ let chunksUploaded = 0;
375
+
376
+ if(fileId != 'unique()') {
377
+ try {
378
+ response = await client.call('get', apiPath + '/' + fileId, apiHeaders);
379
+ chunksUploaded = response.chunksUploaded;
380
+ } catch(e) {
381
+ }
382
+ }
383
+
384
+ let currentChunk = 1;
385
+ let currentPosition = 0;
386
+ let uploadableChunk = new Uint8Array(client.CHUNK_SIZE);
387
+
388
+ const uploadChunk = async (lastUpload = false) => {
389
+ if(currentChunk <= chunksUploaded) {
390
+ return;
315
391
  }
316
392
 
317
- while (offset < size) {
318
- let end = Math.min(offset + libClient.CHUNK_SIZE - 1, size - 1);
393
+ const start = ((currentChunk - 1) * client.CHUNK_SIZE);
394
+ let end = start + currentPosition - 1;
395
+
396
+ if(!lastUpload || currentChunk !== 1) {
397
+ apiHeaders['content-range'] = 'bytes ' + start + '-' + end + '/' + size;
398
+ }
319
399
 
320
- apiHeaders['content-range'] = 'bytes ' + offset + '-' + end + '/' + size;
321
- if (response && response.$id) {
322
- apiHeaders['x-appwrite-id'] = response.$id;
400
+ let uploadableChunkTrimmed;
401
+
402
+ if(currentPosition + 1 >= client.CHUNK_SIZE) {
403
+ uploadableChunkTrimmed = uploadableChunk;
404
+ } else {
405
+ uploadableChunkTrimmed = new Uint8Array(currentPosition);
406
+ for(let i = 0; i <= currentPosition; i++) {
407
+ uploadableChunkTrimmed[i] = uploadableChunk[i];
323
408
  }
409
+ }
410
+
411
+ if (id) {
412
+ apiHeaders['x-appwrite-id'] = id;
413
+ }
414
+
415
+ payload['file'] = { type: 'file', file: new File([uploadableChunkTrimmed], file.filename), filename: file.filename };
324
416
 
325
- const stream = fs.createReadStream(streamFilePath, {
326
- start: offset,
327
- end
417
+ response = await client.call('post', apiPath, apiHeaders, payload);
418
+
419
+ if (!id) {
420
+ id = response['$id'];
421
+ }
422
+
423
+ if (onProgress !== null) {
424
+ onProgress({
425
+ $id: response['$id'],
426
+ progress: Math.min((currentChunk) * client.CHUNK_SIZE, size) / size * 100,
427
+ sizeUploaded: end+1,
428
+ chunksTotal: response['chunksTotal'],
429
+ chunksUploaded: response['chunksUploaded']
328
430
  });
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
- });
431
+ }
432
+
433
+ uploadableChunk = new Uint8Array(client.CHUNK_SIZE);
434
+ currentChunk++;
435
+ currentPosition = 0;
436
+ }
437
+
438
+ for await (const chunk of file.stream) {
439
+ for(const b of chunk) {
440
+ uploadableChunk[currentPosition] = b;
441
+
442
+ currentPosition++;
443
+ if(currentPosition >= client.CHUNK_SIZE) {
444
+ await uploadChunk();
445
+ currentPosition = 0;
340
446
  }
341
- offset += libClient.CHUNK_SIZE;
342
447
  }
343
448
  }
344
-
449
+
450
+ if (currentPosition > 0) { // Check if there's any remaining data for the last chunk
451
+ await uploadChunk(true);
452
+ }
453
+
454
+
345
455
  if (parseOutput) {
346
456
  parse(response)
347
457
  success()
348
458
  }
459
+
349
460
  return response;
461
+
350
462
  }
351
463
 
464
+ /**
465
+ * @typedef {Object} StorageGetFileRequestParams
466
+ * @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).
467
+ * @property {string} fileId File ID.
468
+ * @property {boolean} parseOutput
469
+ * @property {libClient | undefined} sdk
470
+ */
471
+
472
+ /**
473
+ * @param {StorageGetFileRequestParams} params
474
+ */
352
475
  const storageGetFile = async ({ bucketId, fileId, parseOutput = true, sdk = undefined}) => {
353
- /* @param {string} bucketId */
354
- /* @param {string} fileId */
355
-
356
476
  let client = !sdk ? await sdkForProject() : sdk;
477
+
357
478
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
358
479
  let payload = {};
480
+
481
+
359
482
  let response = undefined;
483
+
360
484
  response = await client.call('get', apiPath, {
361
485
  'content-type': 'application/json',
362
486
  }, payload);
487
+
363
488
 
364
489
  if (parseOutput) {
365
490
  parse(response)
366
491
  success()
367
492
  }
493
+
368
494
  return response;
369
495
  }
370
496
 
497
+ /**
498
+ * @typedef {Object} StorageUpdateFileRequestParams
499
+ * @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).
500
+ * @property {string} fileId File unique ID.
501
+ * @property {string} name Name of the file
502
+ * @property {string[]} permissions An array of permission string. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).
503
+ * @property {boolean} parseOutput
504
+ * @property {libClient | undefined} sdk
505
+ */
506
+
507
+ /**
508
+ * @param {StorageUpdateFileRequestParams} params
509
+ */
371
510
  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
511
  let client = !sdk ? await sdkForProject() : sdk;
512
+
378
513
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
379
514
  let payload = {};
380
-
381
- /** Body Params */
382
-
383
515
  if (typeof name !== 'undefined') {
384
516
  payload['name'] = name;
385
517
  }
386
-
387
518
  permissions = permissions === true ? [] : permissions;
388
-
389
519
  if (typeof permissions !== 'undefined') {
390
520
  payload['permissions'] = permissions;
391
521
  }
392
522
 
523
+
393
524
  let response = undefined;
525
+
394
526
  response = await client.call('put', apiPath, {
395
527
  'content-type': 'application/json',
396
528
  }, payload);
529
+
397
530
 
398
531
  if (parseOutput) {
399
532
  parse(response)
400
533
  success()
401
534
  }
535
+
402
536
  return response;
403
537
  }
404
538
 
539
+ /**
540
+ * @typedef {Object} StorageDeleteFileRequestParams
541
+ * @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).
542
+ * @property {string} fileId File ID.
543
+ * @property {boolean} parseOutput
544
+ * @property {libClient | undefined} sdk
545
+ */
546
+
547
+ /**
548
+ * @param {StorageDeleteFileRequestParams} params
549
+ */
405
550
  const storageDeleteFile = async ({ bucketId, fileId, parseOutput = true, sdk = undefined}) => {
406
- /* @param {string} bucketId */
407
- /* @param {string} fileId */
408
-
409
551
  let client = !sdk ? await sdkForProject() : sdk;
552
+
410
553
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
411
554
  let payload = {};
555
+
556
+
412
557
  let response = undefined;
558
+
413
559
  response = await client.call('delete', apiPath, {
414
560
  'content-type': 'application/json',
415
561
  }, payload);
562
+
416
563
 
417
564
  if (parseOutput) {
418
565
  parse(response)
419
566
  success()
420
567
  }
568
+
421
569
  return response;
422
570
  }
423
571
 
572
+ /**
573
+ * @typedef {Object} StorageGetFileDownloadRequestParams
574
+ * @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).
575
+ * @property {string} fileId File ID.
576
+ * @property {boolean} parseOutput
577
+ * @property {libClient | undefined} sdk
578
+ * @property {string} destination
579
+ */
580
+
581
+ /**
582
+ * @param {StorageGetFileDownloadRequestParams} params
583
+ */
424
584
  const storageGetFileDownload = async ({ bucketId, fileId, parseOutput = true, sdk = undefined, destination}) => {
425
- /* @param {string} bucketId */
426
- /* @param {string} fileId */
427
-
428
585
  let client = !sdk ? await sdkForProject() : sdk;
586
+
429
587
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}/download'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
430
588
  let payload = {};
589
+
431
590
  payload['project'] = localConfig.getProject().projectId
432
591
  payload['key'] = globalConfig.getKey();
433
592
  const queryParams = new URLSearchParams(payload);
434
593
  apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
435
594
 
436
- const response = await client.call('get', apiPath, {
595
+ let response = undefined;
596
+
597
+ response = await client.call('get', apiPath, {
437
598
  'content-type': 'application/json',
438
599
  }, payload, 'arraybuffer');
439
600
 
440
601
  fs.writeFileSync(destination, response);
441
-
442
- if (parseOutput) {
443
- log(`File stored in ${destination}`)
602
+
603
+ if (parseOutput) {
604
+ parse(response)
444
605
  success()
445
606
  }
607
+
608
+ return response;
446
609
  }
447
610
 
611
+ /**
612
+ * @typedef {Object} StorageGetFilePreviewRequestParams
613
+ * @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).
614
+ * @property {string} fileId File ID
615
+ * @property {number} width Resize preview image width, Pass an integer between 0 to 4000.
616
+ * @property {number} height Resize preview image height, Pass an integer between 0 to 4000.
617
+ * @property {string} gravity Image crop gravity. Can be one of center,top-left,top,top-right,left,right,bottom-left,bottom,bottom-right
618
+ * @property {number} quality Preview image quality. Pass an integer between 0 to 100. Defaults to 100.
619
+ * @property {number} borderWidth Preview image border in pixels. Pass an integer between 0 to 100. Defaults to 0.
620
+ * @property {string} borderColor Preview image border color. Use a valid HEX color, no # is needed for prefix.
621
+ * @property {number} borderRadius Preview image border radius in pixels. Pass an integer between 0 to 4000.
622
+ * @property {number} opacity Preview image opacity. Only works with images having an alpha channel (like png). Pass a number between 0 to 1.
623
+ * @property {number} rotation Preview image rotation in degrees. Pass an integer between -360 and 360.
624
+ * @property {string} background Preview image background color. Only works with transparent images (png). Use a valid HEX color, no # is needed for prefix.
625
+ * @property {string} output Output format type (jpeg, jpg, png, gif and webp).
626
+ * @property {boolean} parseOutput
627
+ * @property {libClient | undefined} sdk
628
+ * @property {string} destination
629
+ */
630
+
631
+ /**
632
+ * @param {StorageGetFilePreviewRequestParams} params
633
+ */
448
634
  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
635
  let client = !sdk ? await sdkForProject() : sdk;
636
+
464
637
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}/preview'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
465
638
  let payload = {};
466
-
467
- /** Query Params */
468
639
  if (typeof width !== 'undefined') {
469
640
  payload['width'] = width;
470
641
  }
@@ -498,91 +669,135 @@ const storageGetFilePreview = async ({ bucketId, fileId, width, height, gravity,
498
669
  if (typeof output !== 'undefined') {
499
670
  payload['output'] = output;
500
671
  }
672
+
501
673
  payload['project'] = localConfig.getProject().projectId
502
674
  payload['key'] = globalConfig.getKey();
503
675
  const queryParams = new URLSearchParams(payload);
504
676
  apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
505
677
 
506
- const response = await client.call('get', apiPath, {
678
+ let response = undefined;
679
+
680
+ response = await client.call('get', apiPath, {
507
681
  'content-type': 'application/json',
508
682
  }, payload, 'arraybuffer');
509
683
 
510
684
  fs.writeFileSync(destination, response);
511
-
512
- if (parseOutput) {
513
- log(`File stored in ${destination}`)
685
+
686
+ if (parseOutput) {
687
+ parse(response)
514
688
  success()
515
689
  }
690
+
691
+ return response;
516
692
  }
517
693
 
694
+ /**
695
+ * @typedef {Object} StorageGetFileViewRequestParams
696
+ * @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).
697
+ * @property {string} fileId File ID.
698
+ * @property {boolean} parseOutput
699
+ * @property {libClient | undefined} sdk
700
+ * @property {string} destination
701
+ */
702
+
703
+ /**
704
+ * @param {StorageGetFileViewRequestParams} params
705
+ */
518
706
  const storageGetFileView = async ({ bucketId, fileId, parseOutput = true, sdk = undefined, destination}) => {
519
- /* @param {string} bucketId */
520
- /* @param {string} fileId */
521
-
522
707
  let client = !sdk ? await sdkForProject() : sdk;
708
+
523
709
  let apiPath = '/storage/buckets/{bucketId}/files/{fileId}/view'.replace('{bucketId}', bucketId).replace('{fileId}', fileId);
524
710
  let payload = {};
711
+
525
712
  payload['project'] = localConfig.getProject().projectId
526
713
  payload['key'] = globalConfig.getKey();
527
714
  const queryParams = new URLSearchParams(payload);
528
715
  apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
529
716
 
530
- const response = await client.call('get', apiPath, {
717
+ let response = undefined;
718
+
719
+ response = await client.call('get', apiPath, {
531
720
  'content-type': 'application/json',
532
721
  }, payload, 'arraybuffer');
533
722
 
534
723
  fs.writeFileSync(destination, response);
535
-
536
- if (parseOutput) {
537
- log(`File stored in ${destination}`)
724
+
725
+ if (parseOutput) {
726
+ parse(response)
538
727
  success()
539
728
  }
729
+
730
+ return response;
540
731
  }
541
732
 
542
- const storageGetUsage = async ({ range, parseOutput = true, sdk = undefined}) => {
543
- /* @param {string} range */
733
+ /**
734
+ * @typedef {Object} StorageGetUsageRequestParams
735
+ * @property {string} range Date range.
736
+ * @property {boolean} parseOutput
737
+ * @property {libClient | undefined} sdk
738
+ */
544
739
 
740
+ /**
741
+ * @param {StorageGetUsageRequestParams} params
742
+ */
743
+ const storageGetUsage = async ({ range, parseOutput = true, sdk = undefined}) => {
545
744
  let client = !sdk ? await sdkForProject() : sdk;
745
+
546
746
  let apiPath = '/storage/usage';
547
747
  let payload = {};
548
-
549
- /** Query Params */
550
748
  if (typeof range !== 'undefined') {
551
749
  payload['range'] = range;
552
750
  }
751
+
752
+
553
753
  let response = undefined;
754
+
554
755
  response = await client.call('get', apiPath, {
555
756
  'content-type': 'application/json',
556
757
  }, payload);
758
+
557
759
 
558
760
  if (parseOutput) {
559
761
  parse(response)
560
762
  success()
561
763
  }
764
+
562
765
  return response;
563
766
  }
564
767
 
768
+ /**
769
+ * @typedef {Object} StorageGetBucketUsageRequestParams
770
+ * @property {string} bucketId Bucket ID.
771
+ * @property {string} range Date range.
772
+ * @property {boolean} parseOutput
773
+ * @property {libClient | undefined} sdk
774
+ */
775
+
776
+ /**
777
+ * @param {StorageGetBucketUsageRequestParams} params
778
+ */
565
779
  const storageGetBucketUsage = async ({ bucketId, range, parseOutput = true, sdk = undefined}) => {
566
- /* @param {string} bucketId */
567
- /* @param {string} range */
568
-
569
780
  let client = !sdk ? await sdkForProject() : sdk;
781
+
570
782
  let apiPath = '/storage/{bucketId}/usage'.replace('{bucketId}', bucketId);
571
783
  let payload = {};
572
-
573
- /** Query Params */
574
784
  if (typeof range !== 'undefined') {
575
785
  payload['range'] = range;
576
786
  }
787
+
788
+
577
789
  let response = undefined;
790
+
578
791
  response = await client.call('get', apiPath, {
579
792
  'content-type': 'application/json',
580
793
  }, payload);
794
+
581
795
 
582
796
  if (parseOutput) {
583
797
  parse(response)
584
798
  success()
585
799
  }
800
+
586
801
  return response;
587
802
  }
588
803
 
@@ -599,8 +814,8 @@ storage
599
814
  .description(`Create a new storage bucket.`)
600
815
  .requiredOption(`--bucketId <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.`)
601
816
  .requiredOption(`--name <name>`, `Bucket name`)
602
- .option(`--permissions [permissions...]`, `An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](/docs/permissions).`)
603
- .option(`--fileSecurity <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](/docs/permissions).`, parseBool)
817
+ .option(`--permissions [permissions...]`, `An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).`)
818
+ .option(`--fileSecurity <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).`, parseBool)
604
819
  .option(`--enabled <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.`, parseBool)
605
820
  .option(`--maximumFileSize <maximumFileSize>`, `Maximum file size allowed in bytes. Maximum allowed value is 30MB.`, parseInteger)
606
821
  .option(`--allowedFileExtensions [allowedFileExtensions...]`, `Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.`)
@@ -620,8 +835,8 @@ storage
620
835
  .description(`Update a storage bucket by its unique ID.`)
621
836
  .requiredOption(`--bucketId <bucketId>`, `Bucket unique ID.`)
622
837
  .requiredOption(`--name <name>`, `Bucket name`)
623
- .option(`--permissions [permissions...]`, `An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](/docs/permissions).`)
624
- .option(`--fileSecurity <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](/docs/permissions).`, parseBool)
838
+ .option(`--permissions [permissions...]`, `An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).`)
839
+ .option(`--fileSecurity <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).`, parseBool)
625
840
  .option(`--enabled <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.`, parseBool)
626
841
  .option(`--maximumFileSize <maximumFileSize>`, `Maximum file size allowed in bytes. Maximum allowed value is 30MB.`, parseInteger)
627
842
  .option(`--allowedFileExtensions [allowedFileExtensions...]`, `Allowed file extensions. Maximum of 100 extensions are allowed, each 64 characters long.`)
@@ -639,47 +854,47 @@ storage
639
854
  storage
640
855
  .command(`listFiles`)
641
856
  .description(`Get a list of all the user files. You can use the query params to filter your results.`)
642
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
857
+ .requiredOption(`--bucketId <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).`)
643
858
  .option(`--queries [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`)
644
859
  .option(`--search <search>`, `Search term to filter your list results. Max length: 256 chars.`)
645
860
  .action(actionRunner(storageListFiles))
646
861
 
647
862
  storage
648
863
  .command(`createFile`)
649
- .description(`Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](/docs/server/storage#storageCreateBucket) API or directly from your Appwrite console. Larger files should be uploaded using multiple requests with the [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) header to send a partial request with a maximum supported chunk of '5MB'. The 'content-range' header values should always be in bytes. When the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in 'x-appwrite-id' header to allow the server to know that the partial upload is for the existing file and not for a new one. If you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally. `)
650
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
864
+ .description(`Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](https://appwrite.io/docs/server/storage#storageCreateBucket) API or directly from your Appwrite console. Larger files should be uploaded using multiple requests with the [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) header to send a partial request with a maximum supported chunk of '5MB'. The 'content-range' header values should always be in bytes. When the first request is sent, the server will return the **File** object, and the subsequent part request must include the file's **id** in 'x-appwrite-id' header to allow the server to know that the partial upload is for the existing file and not for a new one. If you're creating a new file using one of the Appwrite SDKs, all the chunking logic will be managed by the SDK internally. `)
865
+ .requiredOption(`--bucketId <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).`)
651
866
  .requiredOption(`--fileId <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.`)
652
- .requiredOption(`--file <file>`, `Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](/docs/storage#file-input).`)
653
- .option(`--permissions [permissions...]`, `An array of permission strings. By default, only the current user is granted all permissions. [Learn more about permissions](/docs/permissions).`)
867
+ .requiredOption(`--file <file>`, `Binary file. Appwrite SDKs provide helpers to handle file input. [Learn about file input](https://appwrite.io/docs/storage#file-input).`)
868
+ .option(`--permissions [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).`)
654
869
  .action(actionRunner(storageCreateFile))
655
870
 
656
871
  storage
657
872
  .command(`getFile`)
658
873
  .description(`Get a file by its unique ID. This endpoint response returns a JSON object with the file metadata.`)
659
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
874
+ .requiredOption(`--bucketId <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).`)
660
875
  .requiredOption(`--fileId <fileId>`, `File ID.`)
661
876
  .action(actionRunner(storageGetFile))
662
877
 
663
878
  storage
664
879
  .command(`updateFile`)
665
880
  .description(`Update a file by its unique ID. Only users with write permissions have access to update this resource.`)
666
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
881
+ .requiredOption(`--bucketId <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).`)
667
882
  .requiredOption(`--fileId <fileId>`, `File unique ID.`)
668
883
  .option(`--name <name>`, `Name of the file`)
669
- .option(`--permissions [permissions...]`, `An array of permission string. By default, the current permissions are inherited. [Learn more about permissions](/docs/permissions).`)
884
+ .option(`--permissions [permissions...]`, `An array of permission string. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).`)
670
885
  .action(actionRunner(storageUpdateFile))
671
886
 
672
887
  storage
673
888
  .command(`deleteFile`)
674
889
  .description(`Delete a file by its unique ID. Only users with write permissions have access to delete this resource.`)
675
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
890
+ .requiredOption(`--bucketId <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).`)
676
891
  .requiredOption(`--fileId <fileId>`, `File ID.`)
677
892
  .action(actionRunner(storageDeleteFile))
678
893
 
679
894
  storage
680
895
  .command(`getFileDownload`)
681
896
  .description(`Get a file content by its unique ID. The endpoint response return with a 'Content-Disposition: attachment' header that tells the browser to start downloading the file to user downloads directory.`)
682
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
897
+ .requiredOption(`--bucketId <bucketId>`, `Storage bucket ID. You can create a new storage bucket using the Storage service [server integration](https://appwrite.io/docs/server/storage#createBucket).`)
683
898
  .requiredOption(`--fileId <fileId>`, `File ID.`)
684
899
  .requiredOption(`--destination <path>`, `output file path.`)
685
900
  .action(actionRunner(storageGetFileDownload))
@@ -687,7 +902,7 @@ storage
687
902
  storage
688
903
  .command(`getFilePreview`)
689
904
  .description(`Get a file preview image. Currently, this method supports preview for image files (jpg, png, and gif), other supported formats, like pdf, docs, slides, and spreadsheets, will return the file icon image. You can also pass query string arguments for cutting and resizing your preview image. Preview is supported only for image files smaller than 10MB.`)
690
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
905
+ .requiredOption(`--bucketId <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).`)
691
906
  .requiredOption(`--fileId <fileId>`, `File ID`)
692
907
  .option(`--width <width>`, `Resize preview image width, Pass an integer between 0 to 4000.`, parseInteger)
693
908
  .option(`--height <height>`, `Resize preview image height, Pass an integer between 0 to 4000.`, parseInteger)
@@ -706,7 +921,7 @@ storage
706
921
  storage
707
922
  .command(`getFileView`)
708
923
  .description(`Get a file content by its unique ID. This endpoint is similar to the download method but returns with no 'Content-Disposition: attachment' header.`)
709
- .requiredOption(`--bucketId <bucketId>`, `Storage bucket unique ID. You can create a new storage bucket using the Storage service [server integration](/docs/server/storage#createBucket).`)
924
+ .requiredOption(`--bucketId <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).`)
710
925
  .requiredOption(`--fileId <fileId>`, `File ID.`)
711
926
  .requiredOption(`--destination <path>`, `output file path.`)
712
927
  .action(actionRunner(storageGetFileView))
@@ -727,19 +942,19 @@ storage
727
942
 
728
943
  module.exports = {
729
944
  storage,
730
- storageListBuckets,
731
- storageCreateBucket,
732
- storageGetBucket,
733
- storageUpdateBucket,
734
- storageDeleteBucket,
735
- storageListFiles,
736
- storageCreateFile,
737
- storageGetFile,
738
- storageUpdateFile,
739
- storageDeleteFile,
740
- storageGetFileDownload,
741
- storageGetFilePreview,
742
- storageGetFileView,
743
- storageGetUsage,
744
- storageGetBucketUsage
745
- };
945
+ storageListBuckets,
946
+ storageCreateBucket,
947
+ storageGetBucket,
948
+ storageUpdateBucket,
949
+ storageDeleteBucket,
950
+ storageListFiles,
951
+ storageCreateFile,
952
+ storageGetFile,
953
+ storageUpdateFile,
954
+ storageDeleteFile,
955
+ storageGetFileDownload,
956
+ storageGetFilePreview,
957
+ storageGetFileView,
958
+ storageGetUsage,
959
+ storageGetBucketUsage
960
+ };