box-node-sdk 1.35.0 → 1.37.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.
Files changed (126) hide show
  1. package/CHANGELOG.md +37 -2
  2. package/README.md +1 -1
  3. package/lib/api-request-manager.d.ts +38 -0
  4. package/lib/api-request-manager.js +48 -55
  5. package/lib/api-request-manager.js.map +1 -0
  6. package/lib/api-request.d.ts +141 -0
  7. package/lib/api-request.js +202 -281
  8. package/lib/api-request.js.map +1 -0
  9. package/lib/box-client.d.ts +269 -0
  10. package/lib/box-client.js +551 -713
  11. package/lib/box-client.js.map +1 -0
  12. package/lib/box-node-sdk.d.ts +216 -0
  13. package/lib/box-node-sdk.js +317 -352
  14. package/lib/box-node-sdk.js.map +1 -0
  15. package/lib/chunked-uploader.d.ts +129 -0
  16. package/lib/chunked-uploader.js +287 -358
  17. package/lib/chunked-uploader.js.map +1 -0
  18. package/lib/enterprise-event-stream.d.ts +82 -0
  19. package/lib/enterprise-event-stream.js +189 -203
  20. package/lib/enterprise-event-stream.js.map +1 -0
  21. package/lib/event-stream.d.ts +92 -0
  22. package/lib/event-stream.js +274 -302
  23. package/lib/event-stream.js.map +1 -0
  24. package/lib/managers/collaboration-allowlist.d.ts +137 -0
  25. package/lib/managers/collaboration-allowlist.js +200 -0
  26. package/lib/managers/collaboration-allowlist.js.map +1 -0
  27. package/lib/managers/collaboration-whitelist.d.ts +3 -0
  28. package/lib/managers/collaboration-whitelist.js +8 -222
  29. package/lib/managers/collaboration-whitelist.js.map +1 -0
  30. package/lib/managers/collaborations.d.ts +166 -0
  31. package/lib/managers/collaborations.js +225 -258
  32. package/lib/managers/collaborations.js.map +1 -0
  33. package/lib/managers/collections.d.ts +42 -0
  34. package/lib/managers/collections.js +45 -50
  35. package/lib/managers/collections.js.map +1 -0
  36. package/lib/managers/comments.d.ts +103 -0
  37. package/lib/managers/comments.js +158 -173
  38. package/lib/managers/comments.js.map +1 -0
  39. package/lib/managers/device-pins.d.ts +52 -0
  40. package/lib/managers/device-pins.js +75 -88
  41. package/lib/managers/device-pins.js.map +1 -0
  42. package/lib/managers/enterprise.d.ts +162 -0
  43. package/lib/managers/enterprise.js +168 -199
  44. package/lib/managers/enterprise.js.map +1 -0
  45. package/lib/managers/events.d.ts +177 -0
  46. package/lib/managers/events.js +230 -254
  47. package/lib/managers/events.js.map +1 -0
  48. package/lib/managers/files.d.ts +772 -0
  49. package/lib/managers/files.js +1400 -1602
  50. package/lib/managers/files.js.map +1 -0
  51. package/lib/managers/folders.d.ts +347 -0
  52. package/lib/managers/folders.js +551 -567
  53. package/lib/managers/folders.js.map +1 -0
  54. package/lib/managers/groups.d.ts +202 -0
  55. package/lib/managers/groups.js +238 -287
  56. package/lib/managers/groups.js.map +1 -0
  57. package/lib/managers/legal-hold-policies.d.ts +190 -0
  58. package/lib/managers/legal-hold-policies.js +228 -272
  59. package/lib/managers/legal-hold-policies.js.map +1 -0
  60. package/lib/managers/metadata.d.ts +228 -0
  61. package/lib/managers/metadata.js +265 -328
  62. package/lib/managers/metadata.js.map +1 -0
  63. package/lib/managers/recent-items.d.ts +38 -0
  64. package/lib/managers/recent-items.js +32 -39
  65. package/lib/managers/recent-items.js.map +1 -0
  66. package/lib/managers/retention-policies.d.ts +213 -0
  67. package/lib/managers/retention-policies.js +235 -281
  68. package/lib/managers/retention-policies.js.map +1 -0
  69. package/lib/managers/search.d.ts +82 -0
  70. package/lib/managers/search.js +68 -88
  71. package/lib/managers/search.js.map +1 -0
  72. package/lib/managers/shared-items.d.ts +33 -0
  73. package/lib/managers/shared-items.js +54 -62
  74. package/lib/managers/shared-items.js.map +1 -0
  75. package/lib/managers/storage-policies.d.ts +86 -0
  76. package/lib/managers/storage-policies.js +108 -142
  77. package/lib/managers/storage-policies.js.map +1 -0
  78. package/lib/managers/tasks.d.ts +161 -0
  79. package/lib/managers/tasks.js +219 -260
  80. package/lib/managers/tasks.js.map +1 -0
  81. package/lib/managers/terms-of-service.d.ts +161 -0
  82. package/lib/managers/terms-of-service.js +250 -273
  83. package/lib/managers/terms-of-service.js.map +1 -0
  84. package/lib/managers/trash.d.ts +30 -0
  85. package/lib/managers/trash.js +30 -41
  86. package/lib/managers/trash.js.map +1 -0
  87. package/lib/managers/users.d.ts +131 -0
  88. package/lib/managers/users.js +160 -203
  89. package/lib/managers/users.js.map +1 -0
  90. package/lib/managers/web-links.d.ts +127 -0
  91. package/lib/managers/web-links.js +183 -209
  92. package/lib/managers/web-links.js.map +1 -0
  93. package/lib/managers/webhooks.d.ts +166 -0
  94. package/lib/managers/webhooks.js +312 -305
  95. package/lib/managers/webhooks.js.map +1 -0
  96. package/lib/sessions/anonymous-session.d.ts +69 -0
  97. package/lib/sessions/anonymous-session.js +88 -102
  98. package/lib/sessions/anonymous-session.js.map +1 -0
  99. package/lib/sessions/app-auth-session.d.ts +92 -0
  100. package/lib/sessions/app-auth-session.js +140 -160
  101. package/lib/sessions/app-auth-session.js.map +1 -0
  102. package/lib/sessions/basic-session.d.ts +56 -0
  103. package/lib/sessions/basic-session.js +40 -50
  104. package/lib/sessions/basic-session.js.map +1 -0
  105. package/lib/sessions/persistent-session.d.ts +96 -0
  106. package/lib/sessions/persistent-session.js +191 -211
  107. package/lib/sessions/persistent-session.js.map +1 -0
  108. package/lib/token-manager.d.ts +191 -0
  109. package/lib/token-manager.js +390 -465
  110. package/lib/token-manager.js.map +1 -0
  111. package/lib/util/config.d.ts +86 -0
  112. package/lib/util/config.js +124 -152
  113. package/lib/util/config.js.map +1 -0
  114. package/lib/util/errors.d.ts +50 -0
  115. package/lib/util/errors.js +134 -145
  116. package/lib/util/errors.js.map +1 -0
  117. package/lib/util/exponential-backoff.d.ts +11 -0
  118. package/lib/util/exponential-backoff.js +10 -22
  119. package/lib/util/exponential-backoff.js.map +1 -0
  120. package/lib/util/paging-iterator.d.ts +53 -0
  121. package/lib/util/paging-iterator.js +202 -218
  122. package/lib/util/paging-iterator.js.map +1 -0
  123. package/lib/util/url-path.d.ts +16 -0
  124. package/lib/util/url-path.js +20 -35
  125. package/lib/util/url-path.js.map +1 -0
  126. package/package.json +24 -9
@@ -1,58 +1,54 @@
1
+ "use strict";
1
2
  /**
2
3
  * @fileoverview Manager for the Box Files Resource
3
4
  */
4
-
5
- 'use strict';
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ // ------------------------------------------------------------------------------
9
+ // Requirements
10
+ // ------------------------------------------------------------------------------
11
+ var bluebird_1 = __importDefault(require("bluebird"));
12
+ var crypto_1 = __importDefault(require("crypto"));
13
+ var http_status_1 = __importDefault(require("http-status"));
14
+ var stream_1 = require("stream");
15
+ var url_template_1 = __importDefault(require("url-template"));
16
+ var errors_1 = __importDefault(require("../util/errors"));
17
+ var url_path_1 = __importDefault(require("../util/url-path"));
18
+ var ChunkedUploader = require('../chunked-uploader');
6
19
  // -----------------------------------------------------------------------------
7
20
  // Typedefs
8
21
  // -----------------------------------------------------------------------------
9
-
10
22
  /**
11
- * A representation request type constant
12
- * @typedef {string} FileRepresentationType Different representations we can request from reps endpoint
23
+ * Enum of valid x-rep- hint values for generating representation info
24
+ *
25
+ * @readonly
26
+ * @enum {FileRepresentationType}
13
27
  */
14
-
15
- // -----------------------------------------------------------------------------
16
- // Requirements
17
- // -----------------------------------------------------------------------------
18
-
28
+ var FileRepresentationType;
29
+ (function (FileRepresentationType) {
30
+ FileRepresentationType["PDF"] = "[pdf]";
31
+ FileRepresentationType["THUMBNAIL"] = "[jpg?dimensions=320x320]";
32
+ FileRepresentationType["IMAGE_MEDIUM"] = "[jpg?dimensions=1024x1024][png?dimensions=1024x1024]";
33
+ FileRepresentationType["IMAGE_LARGE"] = "[jpg?dimensions=2048x2048][png?dimensions=2048x2048]";
34
+ FileRepresentationType["EXTRACTED_TEXT"] = "[extracted_text]";
35
+ })(FileRepresentationType || (FileRepresentationType = {}));
19
36
  /**
20
- * @typedef {Object} UploadPart
21
- * @property {string} part_id An 8-character hexadecimal string identifying the part
22
- * @property {int} offset The byte offset of the part within the whole file
23
- * @property {int} size The size of the part in bytes
37
+ * Enum of valid lock types
38
+ *
39
+ * @readonly
40
+ * @enum {LockType}
24
41
  */
25
-
26
- // -----------------------------------------------------------------------------
27
- // Requirements
28
- // -----------------------------------------------------------------------------
29
-
30
- var urlPath = require('../util/url-path'),
31
- errors = require('../util/errors'),
32
- httpStatusCodes = require('http-status'),
33
- crypto = require('crypto'),
34
- Promise = require('bluebird'),
35
- Readable = require('stream').Readable,
36
- urlTemplate = require('url-template'),
37
- ChunkedUploader = require('../chunked-uploader');
38
-
42
+ var LockType;
43
+ (function (LockType) {
44
+ LockType["LOCK"] = "lock";
45
+ LockType["UNLOCK"] = "unlock";
46
+ })(LockType || (LockType = {}));
39
47
  // -----------------------------------------------------------------------------
40
48
  // Private
41
49
  // -----------------------------------------------------------------------------
42
-
43
50
  // Base path for all files endpoints
44
- var BASE_PATH = '/files',
45
- VERSIONS_SUBRESOURCE = '/versions',
46
- WATERMARK_SUBRESOURCE = '/watermark',
47
- UPLOAD_SESSION_SUBRESOURCE = '/upload_sessions',
48
- ZIP_DOWNLOAD_PATH = '/zip_downloads';
49
-
50
- // Enum of valid lock types
51
- var lockTypes = {
52
- LOCK: 'lock',
53
- UNLOCK: 'unlock'
54
- };
55
-
51
+ var BASE_PATH = '/files', VERSIONS_SUBRESOURCE = '/versions', WATERMARK_SUBRESOURCE = '/watermark', UPLOAD_SESSION_SUBRESOURCE = '/upload_sessions', ZIP_DOWNLOAD_PATH = '/zip_downloads';
56
52
  /**
57
53
  * Returns the multipart form value for file upload metadata.
58
54
  * @param {string} parentFolderID - the ID of the parent folder to upload to
@@ -62,20 +58,17 @@ var lockTypes = {
62
58
  * @private
63
59
  */
64
60
  function createFileMetadataFormData(parentFolderID, filename, options) {
65
- // Although the filename and parent folder ID can be specified without using a
66
- // metadata form field, Platform has recommended that we use the metadata form
67
- // field to specify these parameters (one benefit is that UTF-8 characters can
68
- // be specified in the filename).
69
- var metadata = {
70
- name: filename,
71
- parent: { id: parentFolderID }
72
- };
73
-
74
- Object.assign(metadata, options);
75
-
76
- return JSON.stringify(metadata);
61
+ // Although the filename and parent folder ID can be specified without using a
62
+ // metadata form field, Platform has recommended that we use the metadata form
63
+ // field to specify these parameters (one benefit is that UTF-8 characters can
64
+ // be specified in the filename).
65
+ var metadata = {
66
+ name: filename,
67
+ parent: { id: parentFolderID },
68
+ };
69
+ Object.assign(metadata, options);
70
+ return JSON.stringify(metadata);
77
71
  }
78
-
79
72
  /**
80
73
  * Returns the multipart form value for file upload content.
81
74
  * @param {string|Buffer|Stream} content - the content of the file being uploaded
@@ -84,18 +77,17 @@ function createFileMetadataFormData(parentFolderID, filename, options) {
84
77
  * @private
85
78
  */
86
79
  function createFileContentFormData(content, options) {
87
- // The upload API appears to look for a form field that contains a filename
88
- // property and assume that this form field contains the file content. Thus,
89
- // the value of name does not actually matter (as long as it does not conflict
90
- // with other field names). Similarly, the value of options.filename does not
91
- // matter either (as long as it exists), since the upload API will use the
92
- // filename specified in the metadata form field instead.
93
- return {
94
- value: content,
95
- options: Object.assign({ filename: 'unused' }, options)
96
- };
80
+ // The upload API appears to look for a form field that contains a filename
81
+ // property and assume that this form field contains the file content. Thus,
82
+ // the value of name does not actually matter (as long as it does not conflict
83
+ // with other field names). Similarly, the value of options.filename does not
84
+ // matter either (as long as it exists), since the upload API will use the
85
+ // filename specified in the metadata form field instead.
86
+ return {
87
+ value: content,
88
+ options: Object.assign({ filename: 'unused' }, options),
89
+ };
97
90
  }
98
-
99
91
  /**
100
92
  * Poll the representation info URL until representation is generated,
101
93
  * then return content URL template.
@@ -104,1557 +96,1363 @@ function createFileContentFormData(content, options) {
104
96
  * @returns {Promise<string>} A promise resolving to the content URL template
105
97
  */
106
98
  function pollRepresentationInfo(client, infoURL) {
107
-
108
- return client.get(infoURL)
109
- .then(response => {
110
-
111
- if (response.statusCode !== 200) {
112
- throw errors.buildUnexpectedResponseError(response);
113
- }
114
-
115
- var info = response.body;
116
-
117
- switch (info.status.state) {
118
-
119
- case 'success':
120
- case 'viewable':
121
- case 'error':
122
- return info;
123
- case 'none':
124
- case 'pending':
125
- return Promise.delay(1000).then(() => pollRepresentationInfo(client, infoURL));
126
- default:
127
- throw new Error(`Unknown representation status: ${info.status.state}`);
128
- }
129
- });
99
+ return client.get(infoURL).then(function (response /* FIXME */) {
100
+ if (response.statusCode !== 200) {
101
+ throw errors_1.default.buildUnexpectedResponseError(response);
102
+ }
103
+ var info = response.body;
104
+ switch (info.status.state) {
105
+ case 'success':
106
+ case 'viewable':
107
+ case 'error':
108
+ return info;
109
+ case 'none':
110
+ case 'pending':
111
+ return bluebird_1.default.delay(1000).then(function () {
112
+ return pollRepresentationInfo(client, infoURL);
113
+ });
114
+ default:
115
+ throw new Error("Unknown representation status: " + info.status.state);
116
+ }
117
+ });
130
118
  }
131
-
132
119
  // ------------------------------------------------------------------------------
133
120
  // Public
134
121
  // ------------------------------------------------------------------------------
135
-
136
122
  /**
137
123
  * Simple manager for interacting with all 'File' endpoints and actions.
138
124
  *
139
125
  * @param {BoxClient} client The Box API Client that is responsible for making calls to the API
140
126
  * @constructor
141
127
  */
142
- function Files(client) {
143
- // Attach the client, for making API calls
144
- this.client = client;
145
- }
146
-
147
- /**
148
- * Requests a file object with the given ID.
149
- *
150
- * API Endpoint: '/files/:fileID'
151
- * Method: GET
152
- *
153
- * @param {string} fileID - Box ID of the file being requested
154
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
155
- * @param {Function} [callback] - Passed the file information if it was acquired successfully
156
- * @returns {Promise<Object>} A promise resolving to the file object
157
- */
158
- Files.prototype.get = function(fileID, options, callback) {
159
- var params = {
160
- qs: options
161
- };
162
- var apiPath = urlPath(BASE_PATH, fileID);
163
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
164
- };
165
-
166
- /**
167
- * Requests a download URL for a given file.
168
- *
169
- * API Endpoint: '/files/:fileID/content'
170
- * Method: GET
171
- * Special Expected Responses:
172
- * 202 ACCEPTED - Download isn't available yet. Returns an error.
173
- * 302 FOUND - Download is available. A Download URL is returned.
174
- *
175
- * @param {string} fileID - Box ID of the file being requested
176
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
177
- * @param {Function} [callback] - Passed the download URL if request was successful.
178
- * @returns {Promise<string>} A promise resolving to the file's download URL
179
- */
180
- Files.prototype.getDownloadURL = function(fileID, options, callback) {
181
- var params = {
182
- qs: options
183
- };
184
-
185
- var apiPath = urlPath(BASE_PATH, fileID, '/content');
186
-
187
- // Handle Special API Response
188
- return this.client.get(apiPath, params)
189
- .then(response => {
190
-
191
- switch (response.statusCode) {
192
-
193
- // 302 - Found
194
- // No data returned, but the location header points to a download link for that file.
195
- case httpStatusCodes.FOUND:
196
- return response.headers.location;
197
-
198
- // 202 - Download isn't ready yet.
199
- case httpStatusCodes.ACCEPTED:
200
- throw errors.buildResponseError(response, 'Download not ready at this time');
201
-
202
- // Unexpected Response
203
- default:
204
- throw errors.buildUnexpectedResponseError(response);
205
- }
206
- })
207
- .asCallback(callback);
208
- };
209
-
210
- /**
211
- * Requests a Readable Stream for the given file ID.
212
- *
213
- * API Endpoint: '/files/:fileID/content'
214
- * Method: GET
215
- * Special Expected Responses:
216
- * 202 ACCEPTED - Download isn't available yet. Returns an error.
217
- * 302 FOUND - Download is available. A Download stream is returned.
218
- *
219
- * @param {string} fileID - Box ID of the file being requested
220
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
221
- * @param {string} [options.version] - ID of the version of this file to download
222
- * @param {int[]} [options.byteRange] - starting and ending bytes of the file to read, e.g. [0, 99] to read the first 100 bytes
223
- * @param {Function} [callback] - passed the readable stream if request was successful
224
- * @returns {Promise<Readable>} A promise resolving for the file stream
225
- */
226
- Files.prototype.getReadStream = function(fileID, options, callback) {
227
-
228
- options = options || {};
229
-
230
- var downloadStreamOptions = {
231
- streaming: true,
232
- headers: {}
233
- };
234
-
235
- if (options.byteRange) {
236
- var range = options.byteRange;
237
- delete options.byteRange;
238
- downloadStreamOptions.headers.Range = `bytes=${range[0]}-${range[1]}`;
239
- }
240
-
241
- // Get the download URL to download from
242
- return this.getDownloadURL(fileID, options)
243
- // Return a read stream to download the file
244
- .then(url => this.client.get(url, downloadStreamOptions))
245
- .asCallback(callback);
246
- };
247
-
248
- /**
249
- * Requests a Thumbnail for a given file.
250
- *
251
- * API Endpoint: '/files/:fileID/thumbnail.png'
252
- * Method: GET
253
- * Special Expected Responses:
254
- * 200 OK - Thumbnail available. Returns a thumbnail file.
255
- * 202 ACCEPTED - Thumbnail isn't available yet. Returns a `location` URL for a generic placeholder thumbnail.
256
- * 302 FOUND - Unable to generate thumbnail. Returns a `location` URL for a generic placeholder thumbnail.
257
- *
258
- * @param {string} fileID - Box ID of the file being requested
259
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
260
- * @param {Function} [callback] - Passed the thumbnail file or the URL to a placeholder thumbnail if successful.
261
- * @returns {Promise<Object>} A promise resolving to the thumbnail information
262
- */
263
- Files.prototype.getThumbnail = function(fileID, options, callback) {
264
- var params = {
265
- qs: options,
266
- json: false
267
- };
268
-
269
- var apiPath = urlPath(BASE_PATH, fileID, '/thumbnail.png');
270
-
271
- // Handle Special API Response
272
- return this.client.get(apiPath, params)
273
- .then(response => {
274
-
275
- switch (response.statusCode) {
276
-
277
- // 202 - Thumbnail will be generated, but is not ready yet
278
- // 302 - Thumbnail can not be generated
279
- // return the url for a thumbnail placeholder
280
- case httpStatusCodes.ACCEPTED:
281
- case httpStatusCodes.FOUND:
282
- return {
283
- statusCode: response.statusCode,
284
- location: response.headers.location
285
- };
286
-
287
- // 200 - Thumbnail image recieved
288
- // return the thumbnail file
289
- case httpStatusCodes.OK:
290
- return {
291
- statusCode: response.statusCode,
292
- file: response.body
293
- };
294
-
295
- // Unexpected Response
296
- default:
297
- throw errors.buildUnexpectedResponseError(response);
298
- }
299
- })
300
- .asCallback(callback);
301
- };
302
-
303
- /**
304
- * Gets the comments on a file.
305
- *
306
- * API Endpoint: '/files/:fileID/comments'
307
- * Method: GET
308
- *
309
- * @param {string} fileID - Box file id of the file
310
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
311
- * @param {Function} [callback] - passed the file comments if they were successfully acquired
312
- * @returns {Promise<Object>} A promise resolving to the collection of comments
313
- */
314
- Files.prototype.getComments = function(fileID, options, callback) {
315
- var params = {
316
- qs: options
317
- };
318
- var apiPath = urlPath(BASE_PATH, fileID, '/comments');
319
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
320
- };
321
-
322
-
323
- /**
324
- * Update some information about a given file.
325
- *
326
- * API Endpoint: '/files/:fileID'
327
- * Method: PUT
328
- *
329
- * @param {string} fileID - Box ID of the file being requested
330
- * @param {Object} updates - File fields to update
331
- * @param {string} [updates.etag] Only apply the updates if the file etag matches
332
- * @param {Function} [callback] - Passed the updated file information if it was acquired successfully
333
- * @returns {Promise<Object>} A promise resolving to the update file object
334
- */
335
- Files.prototype.update = function(fileID, updates, callback) {
336
-
337
- var params = {
338
- body: updates
339
- };
340
-
341
- if (updates && updates.etag) {
342
- params.headers = {
343
- 'If-Match': updates.etag
344
- };
345
- delete updates.etag;
346
- }
347
-
348
- var apiPath = urlPath(BASE_PATH, fileID);
349
- return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
350
- };
351
-
352
- /**
353
- * Add a file to a given collection
354
- *
355
- * API Endpoint: '/files/:fileID'
356
- * Method: PUT
357
- *
358
- * @param {string} fileID - The file to add to the collection
359
- * @param {string} collectionID - The collection to add the file to
360
- * @param {Function} [callback] - Passed the updated file if successful, error otherwise
361
- * @returns {Promise<Object>} A promise resolving to the updated file object
362
- */
363
- Files.prototype.addToCollection = function(fileID, collectionID, callback) {
364
-
365
- return this.get(fileID, { fields: 'collections' })
366
- .then(data => {
367
-
368
- var collections = data.collections || [];
369
-
370
- // Convert to correct format
371
- collections = collections.map(c => ({ id: c.id }));
372
-
373
- if (!collections.find(c => c.id === collectionID)) {
374
-
375
- collections.push({ id: collectionID });
376
- }
377
-
378
- return this.update(fileID, { collections });
379
- })
380
- .asCallback(callback);
381
- };
382
-
383
- /**
384
- * Remove a file from a given collection
385
- *
386
- * API Endpoint: '/files/:fileID'
387
- * Method: PUT
388
- *
389
- * @param {string} fileID - The file to remove from the collection
390
- * @param {string} collectionID - The collection to remove the file from
391
- * @param {Function} [callback] - Passed the updated file if successful, error otherwise
392
- * @returns {Promise<Object>} A promise resolving to the updated file object
393
- */
394
- Files.prototype.removeFromCollection = function(fileID, collectionID, callback) {
395
-
396
- return this.get(fileID, { fields: 'collections' })
397
- .then(data => {
398
-
399
- var collections = data.collections || [];
400
- // Convert to correct object format and remove the specified collection
401
- collections = collections.map(c => ({ id: c.id })).filter(c => c.id !== collectionID);
402
-
403
- return this.update(fileID, { collections });
404
- })
405
- .asCallback(callback);
406
- };
407
-
408
- /**
409
- * Move a file into a new parent folder.
410
- *
411
- * API Endpoint: '/files/:fileID'
412
- * Method: PUT
413
- *
414
- * @param {string} fileID - The Box ID of the file being requested
415
- * @param {string} newParentID - The Box ID for the new parent folder. '0' to move to All Files.
416
- * @param {Function} [callback] - Passed the updated file information if it was acquired successfully
417
- * @returns {Promise<Object>} A promise resolving to the updated file object
418
- */
419
- Files.prototype.move = function(fileID, newParentID, callback) {
420
- var params = {
421
- body: {
422
- parent: {
423
- id: newParentID
424
- }
425
- }
426
- };
427
- var apiPath = urlPath(BASE_PATH, fileID);
428
- return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
429
- };
430
-
431
- /**
432
- * Copy a file into a new folder.
433
- *
434
- * API Endpoint: '/files/:fileID/copy
435
- * Method: POST
436
- *
437
- * @param {string} fileID - The Box ID of the file being requested
438
- * @param {string} newParentID - The Box ID for the new parent folder. '0' to copy to All Files.
439
- * @param {Object} [options] - Optional parameters for the copy operation, can be left null in most cases
440
- * @param {string} [options.name] - A new name to use if there is an identically-named item in the new parent folder
441
- * @param {Function} [callback] - passed the new file info if call was successful
442
- * @returns {Promise<Object>} A promise resolving to the new file object
443
- */
444
- Files.prototype.copy = function(fileID, newParentID, options, callback) {
445
-
446
- // @NOTE(mwiller) 2016-10-25: Shuffle arguments to maintain backward compatibility
447
- // This can be removed at the v2.0 update
448
- if (typeof options === 'function') {
449
- callback = options;
450
- options = {};
451
- }
452
-
453
- options = options || {};
454
-
455
- options.parent = {
456
- id: newParentID
457
- };
458
-
459
- var params = {
460
- body: options
461
- };
462
- var apiPath = urlPath(BASE_PATH, fileID, '/copy');
463
- return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
464
- };
465
-
466
- /**
467
- * Delete a given file.
468
- *
469
- * API Endpoint: '/files/:fileID'
470
- * Method: DELETE
471
- *
472
- * @param {string} fileID - Box ID of the file being requested
473
- * @param {Object} [options] Optional parameters
474
- * @param {string} [options.etag] Only delete the file if the etag value matches
475
- * @param {Function} [callback] - Empty response body passed if successful.
476
- * @returns {Promise<void>} A promise resolving to nothing
477
- */
478
- Files.prototype.delete = function(fileID, options, callback) {
479
-
480
- // Switch around arguments if necessary for backwards compatibility
481
- if (typeof options === 'function') {
482
- callback = options;
483
- options = {};
484
- }
485
-
486
- var params = {};
487
-
488
- if (options && options.etag) {
489
- params.headers = {
490
- 'If-Match': options.etag
491
- };
492
- }
493
-
494
- var apiPath = urlPath(BASE_PATH, fileID);
495
- return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, params, callback);
496
- };
497
-
498
- /**
499
- * Get preflight information for a new file upload. Without any file data,
500
- * this will return an upload URL and token to be used when uploading the file.
501
- * Using this upload URL will allow for the fastest upload, and the one-time
502
- * token can be passed to a worker or other client to actually perform the
503
- * upload with. If file data (e.g. size, parent, name) is passed, it will be
504
- * validated as if the actual file were being uploaded. This enables checking
505
- * of preconditions such as name uniqueness and available storage space before
506
- * attempting a large file upload.
507
- *
508
- * API Endpoint: '/files/content'
509
- * Method: OPTIONS
510
- *
511
- * @param {string} parentFolderID - The id of the parent folder to upload to
512
- * @param {Object} [fileData] - Optional data about the file to be uploaded
513
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
514
- * @param {Function} [callback] - Called with upload data if successful, or err if the upload would not succeed
515
- * @returns {Promise<Object>} A promise resolving to the upload data
516
- */
517
- Files.prototype.preflightUploadFile = function(parentFolderID, fileData, options, callback) {
518
- var params = {
519
- body: {
520
- parent: {
521
- id: parentFolderID
522
- }
523
- },
524
- qs: options
525
- };
526
-
527
- if (fileData) {
528
- Object.assign(params.body, fileData);
529
- }
530
- var apiPath = urlPath(BASE_PATH, '/content');
531
- return this.client.wrapWithDefaultHandler(this.client.options)(apiPath, params, callback);
532
- };
533
-
534
- /**
535
- * Get preflight information for a file version upload. Without any file data,
536
- * this will return an upload URL and token to be used when uploading the file.
537
- * Using this upload URL will allow for the fastest upload, and the one-time
538
- * token can be passed to a worker or other client to actually perform the
539
- * upload with. If file data (e.g. size, parent, name) is passed, it will be
540
- * validated as if the actual file were being uploaded. This enables checking
541
- * of preconditions such as name uniqueness and available storage space before
542
- * attempting a large file upload.
543
- *
544
- * API Endpoint: '/files/:fileID/content'
545
- * Method: OPTIONS
546
- *
547
- * @param {string} fileID - The file ID to which a new version will be uploaded
548
- * @param {Object} [fileData] - Optional data about the file to be uploaded
549
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
550
- * @param {Function} [callback] - Called with upload data if successful, or err if the upload would not succeed
551
- * @returns {Promise<Object>} A promise resolving to the upload data
552
- */
553
- Files.prototype.preflightUploadNewFileVersion = function(fileID, fileData, options, callback) {
554
- var params = {
555
- qs: options
556
- };
557
-
558
- if (fileData) {
559
- params.body = fileData;
560
- }
561
-
562
- var apiPath = urlPath(BASE_PATH, fileID, '/content');
563
- return this.client.wrapWithDefaultHandler(this.client.options)(apiPath, params, callback);
564
- };
565
-
566
- /**
567
- * If there are previous versions of this file, this method can be used to promote one of the older
568
- * versions to the top of the stack. This actually mints a copy of the old version and puts it on
569
- * the top of the versions stack. The file will have the exact same contents, the same SHA1/etag,
570
- * and the same name as the original. Other properties such as comments do not get updated to their former values.
571
- *
572
- * API Endpoint: '/files/:fileID/versions/current'
573
- * Method: POST
574
- *
575
- * @param {string} fileID - The file ID which version will be promoted
576
- * @param {string} versionID - The ID of the file_version that you want to make current
577
- * @param {Function} [callback] - Passed the promoted file version information if successful, error otherwise
578
- * @returns {Promise<Object>} A promise resolving to the promoted file version
579
- */
580
- Files.prototype.promoteVersion = function(fileID, versionID, callback) {
581
- var apiPath = urlPath(BASE_PATH, fileID, VERSIONS_SUBRESOURCE, '/current'),
582
- params = {
583
- body: {
584
- type: 'file_version',
585
- id: versionID
586
- }
587
- };
588
-
589
- return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
590
- };
591
-
592
- /**
593
- * Uploads a new file. Unlike non-upload methods, this method will not perform any retries.
594
- * This method currently does not support any optional parameters such as contentModifiedAt.
595
- *
596
- * API Endpoint: '/files/content'
597
- * Method: POST
598
- *
599
- * @param {string} parentFolderID - the id of the parent folder to upload to
600
- * @param {string} filename - the file name that the uploaded file should have
601
- * @param {string|Buffer|ReadStream} content - the content of the file. It can be a string, a Buffer, or a read stream
602
- * (like that returned by fs.createReadStream()).
603
- * @param {Object} [options] - Optional parameters
604
- * @param {string} [options.content_created_at] - RFC 3339 timestamp when the file was created
605
- * @param {string} [options.content_modified_at] - RFC 3339 timestamp when the file was last modified
606
- * @param {int} [options.content_length] - Optional length of the content. Required if content is a read stream of any type other than fs stream.
607
- * @param {Function} [callback] - called with data about the upload if successful, or an error if the
608
- * upload failed
609
- * @returns {Promise<Object>} A promise resolving to the uploaded file
610
- */
611
- Files.prototype.uploadFile = function(parentFolderID, filename, content, options, callback) {
612
-
613
- // Shuffle around optional parameter
614
- if (typeof options === 'function') {
615
- callback = options;
616
- options = {};
617
- }
618
-
619
- var formOptions = {};
620
- if (options && options.hasOwnProperty('content_length')) {
621
- formOptions.knownLength = options.content_length;
622
- // Delete content_length from options so it's not added to the attributes of the form
623
- delete options.content_length;
624
- }
625
-
626
- var apiPath = urlPath(BASE_PATH, '/content'),
627
- multipartFormData = {
628
- attributes: createFileMetadataFormData(parentFolderID, filename, options),
629
- content: createFileContentFormData(content, formOptions)
630
- };
631
-
632
- return this.client.wrapWithDefaultHandler(this.client.upload)(apiPath, null, multipartFormData, callback);
633
- };
634
-
635
- /**
636
- * Uploads a new version of a file. Unlike non-upload methods, this method will not perform any retries.
637
- * This method currently does not support any optional parameters such as contentModifiedAt.
638
- *
639
- * API Endpoint: '/files/:fileID/content'
640
- * Method: POST
641
- *
642
- * @param {string} fileID - the id of the file to upload a new version of
643
- * @param {string|Buffer|Stream} content - the content of the file. It can be a string, a Buffer, or a read stream
644
- * (like that returned by fs.createReadStream()).
645
- * @param {Object} [options] - Optional parameters
646
- * @param {string} [options.content_modified_at] - RFC 3339 timestamp when the file was last modified
647
- * @param {string} [options.name] - A new name for the file
648
- * @param {int} [options.content_length] - Optional length of the content. Required if content is a read stream of any type other than fs stream.
649
- * @param {Function} [callback] - called with data about the upload if successful, or an error if the
650
- * upload failed
651
- * @returns {Promise<Object>} A promise resolving to the uploaded file
652
- */
653
- Files.prototype.uploadNewFileVersion = function(fileID, content, options, callback) {
654
-
655
- // Shuffle around optional parameter
656
- if (typeof options === 'function') {
657
- callback = options;
658
- options = {};
659
- }
660
-
661
- var apiPath = urlPath(BASE_PATH, fileID, '/content'),
662
- multipartFormData = {};
663
-
664
-
665
- var formOptions = {};
666
- if (options) {
667
- if (options.hasOwnProperty('content_length')) {
668
- formOptions.knownLength = options.content_length;
669
- // Delete content_length from options so it's not added to the attributes of the form
670
- delete options.content_length;
671
- }
672
- multipartFormData.attributes = JSON.stringify(options);
673
- }
674
-
675
- multipartFormData.content = createFileContentFormData(content, formOptions);
676
-
677
- return this.client.wrapWithDefaultHandler(this.client.upload)(apiPath, null, multipartFormData, callback);
678
- };
679
-
680
- /**
681
- * Retrieves all metadata associated with a file.
682
- *
683
- * API Endpoint: '/files/:fileID/metadata'
684
- * Method: GET
685
- *
686
- * @param {string} fileID - the ID of the file to get metadata for
687
- * @param {Function} [callback] - called with an array of metadata when successful
688
- * @returns {Promise<Object>} A promise resolving to a collection of metadata on the file
689
- */
690
- Files.prototype.getAllMetadata = function(fileID, callback) {
691
-
692
- var apiPath = urlPath(BASE_PATH, fileID, 'metadata');
693
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, null, callback);
694
- };
695
-
696
- /**
697
- * Retrieve a single metadata template instance for a file.
698
- *
699
- * API Endpoint: '/files/:fileID/metadata/:scope/:template'
700
- * Method: GET
701
- *
702
- * @param {string} fileID - The ID of the file to retrive the metadata of
703
- * @param {string} scope - The scope of the metadata template, e.g. "global"
704
- * @param {string} template - The metadata template to retrieve
705
- * @param {Function} [callback] - Passed the metadata template if successful
706
- * @returns {Promise<Object>} A promise resolving to the metadata template
707
- */
708
- Files.prototype.getMetadata = function(fileID, scope, template, callback) {
709
-
710
- var apiPath = urlPath(BASE_PATH, fileID, 'metadata', scope, template);
711
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, null, callback);
712
- };
713
-
714
- /**
715
- * Adds metadata to a file. Metadata must either match a template schema or
716
- * be placed into the unstructured "properties" template in global scope.
717
- *
718
- * API Endpoint: '/files/:fileID/metadata/:scope/:template'
719
- * Method: POST
720
- *
721
- * @param {string} fileID - The ID of the file to add metadata to
722
- * @param {string} scope - The scope of the metadata template, e.g. "enterprise"
723
- * @param {string} template - The metadata template schema to add
724
- * @param {Object} data - Key/value pairs tp add as metadata
725
- * @param {Function} [callback] - Called with error if unsuccessful
726
- * @returns {Promise<Object>} A promise resolving to the new metadata
727
- */
728
- Files.prototype.addMetadata = function(fileID, scope, template, data, callback) {
729
-
730
- var apiPath = urlPath(BASE_PATH, fileID, 'metadata', scope, template),
731
- params = {
732
- body: data
733
- };
734
-
735
- return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
736
- };
737
-
738
- /**
739
- * Updates a metadata template instance with JSON Patch-formatted data.
740
- *
741
- * API Endpoint: '/files/:fileID/metadata/:scope/:template'
742
- * Method: PUT
743
- *
744
- * @param {string} fileID - The file to update metadata for
745
- * @param {string} scope - The scope of the template to update
746
- * @param {string} template - The template to update
747
- * @param {Object} patch - The patch data
748
- * @param {Function} [callback] - Called with updated metadata if successful
749
- * @returns {Promise<Object>} A promise resolving to the updated metadata
750
- */
751
- Files.prototype.updateMetadata = function(fileID, scope, template, patch, callback) {
752
-
753
- var apiPath = urlPath(BASE_PATH, fileID, 'metadata', scope, template),
754
- params = {
755
- body: patch,
756
- headers: {
757
- 'Content-Type': 'application/json-patch+json'
758
- }
759
- };
760
-
761
- return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
762
- };
763
-
764
- /**
765
- * Sets metadata on a file, overwriting any metadata that exists for the provided keys.
766
- *
767
- * @param {string} fileID - The file to set metadata on
768
- * @param {string} scope - The scope of the metadata template
769
- * @param {string} template - The key of the metadata template
770
- * @param {Object} metadata - The metadata to set
771
- * @param {Function} [callback] - Called with updated metadata if successful
772
- * @returns {Promise<Object>} A promise resolving to the updated metadata
773
- */
774
- Files.prototype.setMetadata = function(fileID, scope, template, metadata, callback) {
775
-
776
- return this.addMetadata(fileID, scope, template, metadata)
777
- .catch(err => {
778
-
779
- if (err.statusCode !== 409) {
780
- throw err;
781
- }
782
-
783
- // Metadata already exists on the file; update instead
784
- var updates = Object.keys(metadata).map(key => ({
785
- op: 'add',
786
- path: `/${key}`,
787
- value: metadata[key],
788
- }));
789
-
790
- return this.updateMetadata(fileID, scope, template, updates);
791
- })
792
- .asCallback(callback);
793
- };
794
-
795
- /**
796
- * Deletes a metadata template from a file.
797
- *
798
- * API Endpoint: '/files/:fileID/metadata/:scope/:template'
799
- * Method: DELETE
800
- *
801
- * @param {string} fileID - The ID of the file to remove metadata from
802
- * @param {string} scope - The scope of the metadata template
803
- * @param {string} template - The template to remove from the file
804
- * @param {Function} [callback] - Called with nothing if successful, error otherwise
805
- * @returns {Promise<void>} A promise resolving to nothing
806
- */
807
- Files.prototype.deleteMetadata = function(fileID, scope, template, callback) {
808
-
809
- var apiPath = urlPath(BASE_PATH, fileID, 'metadata', scope, template);
810
- return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, null, callback);
811
- };
812
-
813
- /**
814
- * Permanently deletes an item that is in the trash. The item will no longer exist in Box. This action cannot be undone.
815
- *
816
- * API Endpoint: '/files/:fileID/trash'
817
- * Method: DELETE
818
- *
819
- * @param {string} fileID - The ID of the file to remove metadata from
820
- * @param {Object} [options] Optional parameters
821
- * @param {string} [options.etag] Only delete the file if the etag matches
822
- * @param {Function} [callback] - Called with nothing if successful, error otherwise
823
- * @returns {Promise<void>} A promise resolving to nothing
824
- */
825
- Files.prototype.deletePermanently = function(fileID, options, callback) {
826
-
827
- if (typeof options === 'function') {
828
- callback = options;
829
- options = {};
830
- }
831
-
832
- var params = {};
833
-
834
- if (options && options.etag) {
835
- params.headers = {
836
- 'If-Match': options.etag
837
- };
838
- }
839
-
840
- var apiPath = urlPath(BASE_PATH, fileID, '/trash');
841
- return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, params, callback);
842
- };
843
-
844
- /**
845
- * Retrieves a file that has been moved to the trash.
846
- *
847
- * API Endpoint: '/files/:fileID/trash'
848
- * Method: GET
849
- *
850
- * @param {string} fileID - The ID of the file being requested
851
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
852
- * @param {Function} [callback] - Passed the trashed file information if successful, error otherwise
853
- * @returns {Promise<Object>} A promise resolving to the trashed file
854
- */
855
- Files.prototype.getTrashedFile = function(fileID, options, callback) {
856
-
857
- var params = {
858
- qs: options
859
- };
860
-
861
- var apiPath = urlPath(BASE_PATH, fileID, 'trash');
862
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
863
- };
864
-
865
- /**
866
- * Retrieves all of the tasks for given file.
867
- *
868
- * API Endpoint: '/files/:fileID/tasks'
869
- * Method: GET
870
- *
871
- * @param {string} fileID - The ID of the file to get tasks for
872
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
873
- * @param {Function} [callback] - Passed the file tasks if successful, error otherwise
874
- * @returns {Promise<Object>} A promise resolving to a collections of tasks on the file
875
- */
876
- Files.prototype.getTasks = function(fileID, options, callback) {
877
-
878
- var params = {
879
- qs: options
880
- };
881
-
882
- var apiPath = urlPath(BASE_PATH, fileID, '/tasks');
883
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
884
- };
885
-
886
- /**
887
- * Used to retrieve an expiring URL for creating an embedded preview session.
888
- * The URL will expire after 60 seconds and the preview session will expire after 60 minutes.
889
- *
890
- * API Endpoint: '/files/:fileID?fields=expiring_embed_link'
891
- * Method: GET
892
- *
893
- * @param {string} fileID - The ID of the file to generate embed link for
894
- * @param {Function} [callback] - Passed with the embed link if successful, error otherwise
895
- * @returns {Promise<string>} A promise resolving to the file embed link URL
896
- */
897
- Files.prototype.getEmbedLink = function(fileID, callback) {
898
-
899
- var params = {
900
- qs: {
901
- fields: 'expiring_embed_link'
902
- }
903
- };
904
-
905
- var apiPath = urlPath(BASE_PATH, fileID);
906
- return this.client.get(apiPath, params)
907
- .then(response => {
908
-
909
- if (response.statusCode !== httpStatusCodes.OK) {
910
- throw errors.buildUnexpectedResponseError(response);
911
- }
912
-
913
- return response.body.expiring_embed_link.url;
914
- })
915
- .asCallback(callback);
916
- };
917
-
918
- /**
919
- * Locks a file.
920
- *
921
- * API Endpoint: '/files/:fileID'
922
- * Method: PUT
923
- *
924
- * @param {string} fileID - The ID of the file to lock
925
- * @param {Object} [options] - Optional parameters, can be left null in most cases
926
- * @param {?string} [options.expires_at] - The time the lock expires
927
- * @param {boolean} [options.is_download_prevented] - Whether or not the file can be downloaded while locked
928
- * @param {Function} [callback] - Passed with the locked file information if successful, error otherwise
929
- * @returns {Promise<Object>} A promise resolving to the locked file object
930
- */
931
- Files.prototype.lock = function(fileID, options, callback) {
932
-
933
- var apiPath = urlPath(BASE_PATH, fileID),
934
- params = {
935
- body: {
936
- lock: {
937
- type: lockTypes.LOCK
938
- }
939
- }
940
- };
941
-
942
- Object.assign(params.body.lock, options);
943
-
944
- return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
945
- };
946
-
947
- /**
948
- * Unlocks a file.
949
- *
950
- * API Endpoint: '/files/:fileID'
951
- * Method: PUT
952
- *
953
- * @param {string} fileID - The ID of the file to unlock
954
- * @param {Function} [callback] - Passed with the unlocked file information if successful, error otherwise
955
- * @returns {Promise<Object>} A promise resolving to the unlocked file object
956
- */
957
- Files.prototype.unlock = function(fileID, callback) {
958
-
959
- var apiPath = urlPath(BASE_PATH, fileID),
960
- params = {
961
- body: {
962
- lock: null
963
- }
964
- };
965
-
966
- return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
967
- };
968
-
969
- /**
970
- * Restores an item that has been moved to the trash. Default behavior is to
971
- * restore the item to the folder it was in before it was moved to the trash.
972
- * If that parent folder no longer exists or if there is now an item with the
973
- * same name in that parent folder, the new parent folder and/or new name will
974
- * need to be included in the request.
975
- *
976
- * API Endpoint: '/files/:fileID'
977
- * Method: POST
978
- *
979
- * @param {string} fileID - The ID of the file to restore
980
- * @param {Object} [options] - Optional parameters, can be left null in most cases
981
- * @param {string} [options.name] - The new name for this item
982
- * @param {string} [options.parent_id] - The new parent folder for this item
983
- * @param {Function} [callback] - Called with item information if successful, error otherwise
984
- * @returns {Promise<Object>} A promise resolving to the restored file object
985
- */
986
- Files.prototype.restoreFromTrash = function(fileID, options, callback) {
987
-
988
- // Set up the parent_id parameter
989
- if (options && options.parent_id) {
990
-
991
- options.parent = {
992
- id: options.parent_id
993
- };
994
-
995
- delete options.parent_id;
996
- }
997
-
998
- var apiPath = urlPath(BASE_PATH, fileID),
999
- params = {
1000
- body: options || {}
1001
- };
1002
-
1003
- return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
1004
- };
1005
-
1006
- /**
1007
- * If there are previous versions of this file, this method can be used to retrieve information
1008
- * about the older versions.
1009
- *
1010
- * API Endpoint: '/files/:fileID/versions'
1011
- * Method: GET
1012
- *
1013
- * @param {string} fileID - The ID of the file to view version for
1014
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
1015
- * @param {Function} [callback] - Passed a list of previous file versions if successful, error otherwise
1016
- * @returns {Promise<Object>} A promise resolving to the collection of file versions
1017
- */
1018
- Files.prototype.getVersions = function(fileID, options, callback) {
1019
-
1020
- var apiPath = urlPath(BASE_PATH, fileID, VERSIONS_SUBRESOURCE),
1021
- params = {
1022
- qs: options
1023
- };
1024
-
1025
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
1026
- };
1027
-
1028
- /**
1029
- * Used to retrieve the watermark for a corresponding Box file.
1030
- *
1031
- * API Endpoint: '/files/:fileID/watermark'
1032
- * Method: GET
1033
- *
1034
- * @param {string} fileID - The Box ID of the file to get watermark for
1035
- * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
1036
- * @param {Function} [callback] - Passed the watermark information if successful, error otherwise
1037
- * @returns {Promise<Object>} A promise resolving to the watermark info
1038
- */
1039
- Files.prototype.getWatermark = function(fileID, options, callback) {
1040
-
1041
- var apiPath = urlPath(BASE_PATH, fileID, WATERMARK_SUBRESOURCE),
1042
- params = {
1043
- qs: options
1044
- };
1045
-
1046
- return this.client.get(apiPath, params)
1047
- .then(response => {
1048
-
1049
- if (response.statusCode !== 200) {
1050
- throw errors.buildUnexpectedResponseError(response);
1051
- }
1052
-
1053
- return response.body.watermark;
1054
- })
1055
- .asCallback(callback);
1056
- };
1057
-
1058
- /**
1059
- * Used to apply or update the watermark for a corresponding Box file.
1060
- *
1061
- * API Endpoint: '/files/:fileID/watermark'
1062
- * Method: PUT
1063
- *
1064
- * @param {string} fileID - The Box ID of the file to update watermark for
1065
- * @param {Object} [options] - Optional parameters, can be left null
1066
- * @param {Function} [callback] - Passed the watermark information if successful, error otherwise
1067
- * @returns {Promise<Object>} A promise resolving to the watermark info
1068
- */
1069
- Files.prototype.applyWatermark = function(fileID, options, callback) {
1070
- var apiPath = urlPath(BASE_PATH, fileID, WATERMARK_SUBRESOURCE),
1071
- params = {
1072
- body: {
1073
- watermark: {
1074
- imprint: 'default' // Currently the API only supports default imprint
1075
- }
1076
- }
1077
- };
1078
-
1079
- Object.assign(params.body.watermark, options);
1080
-
1081
- return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
1082
- };
1083
-
1084
- /**
1085
- * Used to remove the watermark for a corresponding Box file.
1086
- *
1087
- * API Endpoint: '/files/:fileID/watermark'
1088
- * Method: DELETE
1089
- *
1090
- * @param {string} fileID - The Box ID of the file to remove watermark from
1091
- * @param {Function} [callback] - Empty response body passed if successful, error otherwise
1092
- * @returns {Promise<void>} A promise resolving to nothing
1093
- */
1094
- Files.prototype.removeWatermark = function(fileID, callback) {
1095
-
1096
- var apiPath = urlPath(BASE_PATH, fileID, WATERMARK_SUBRESOURCE);
1097
-
1098
- return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, null, callback);
1099
- };
1100
-
1101
- /**
1102
- * Discards a specific file version to the trash. Depending on the enterprise settings
1103
- * for this user, the item will either be actually deleted from Box or moved to the trash.
1104
- *
1105
- * API Endpoint: '/files/:fileID/version/:versionID'
1106
- * Method: DELETE
1107
- *
1108
- * @param {string} fileID - The file ID which old version will be moved to the trash or delete permanently
1109
- * @param {string} versionID - The ID of the version to move to the trash or delete permanently
1110
- * @param {Object} [options] Optional parameters
1111
- * @param {string} [options.etag] Only delete the version of the file etag matches
1112
- * @param {Function} [callback] - Empty response body, error otherwise
1113
- * @returns {Promise<void>} A promise resolving to nothing
1114
- */
1115
- Files.prototype.deleteVersion = function(fileID, versionID, options, callback) {
1116
-
1117
- // Switch around arguments if necessary for backwwards compatibility
1118
- if (typeof options === 'function') {
1119
- callback = options;
1120
- options = {};
1121
- }
1122
-
1123
- var params = {};
1124
-
1125
- if (options && options.etag) {
1126
- params.headers = {
1127
- 'If-Match': options.etag
1128
- };
1129
- }
1130
-
1131
- var apiPath = urlPath(BASE_PATH, fileID, VERSIONS_SUBRESOURCE, versionID);
1132
-
1133
- return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, params, callback);
1134
- };
1135
-
1136
- /**
1137
- * Creates a session used to upload a new file in chunks.. This will first
1138
- * verify that the file can be created and then open a session for uploading
1139
- * pieces of the file.
1140
- *
1141
- * API Endpoint: '/files/upload_sessions'
1142
- * Method: POST
1143
- *
1144
- * @param {string} folderID - The ID of the folder to upload the file to
1145
- * @param {int} size - The size of the file that will be uploaded
1146
- * @param {string} name - The name of the file to be created
1147
- * @param {Function} [callback] - Passed the upload session info if successful
1148
- * @returns {Promise<Object>} A promise resolving to the new upload session object
1149
- */
1150
- Files.prototype.createUploadSession = function(folderID, size, name, callback) {
1151
-
1152
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE),
1153
- params = {
1154
- body: {
1155
- folder_id: folderID,
1156
- file_size: size,
1157
- file_name: name
1158
- }
1159
- };
1160
-
1161
- return this.client.wrapWithDefaultHandler(this.client.post)(apiURL, params, callback);
1162
- };
1163
-
1164
- /**
1165
- * Creates a session used to upload a new version of a file in chunks. This
1166
- * will first verify that the version can be created and then open a session for
1167
- * uploading pieces of the file.
1168
- *
1169
- * API Endpoint: '/files/:fileID/upload_sessions'
1170
- * Method: POST
1171
- *
1172
- * @param {string} fileID - The ID of the file to upload a new version of
1173
- * @param {int} size - The size of the file that will be uploaded
1174
- * @param {Function} [callback] - Passed the upload session info if successful
1175
- * @returns {Promise<Object>} A promise resolving to the new upload session object
1176
- */
1177
- Files.prototype.createNewVersionUploadSession = function(fileID, size, callback) {
1178
-
1179
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, fileID, UPLOAD_SESSION_SUBRESOURCE),
1180
- params = {
1181
- body: {
1182
- file_size: size
1183
- }
1184
- };
1185
-
1186
- return this.client.wrapWithDefaultHandler(this.client.post)(apiURL, params, callback);
1187
- };
1188
-
1189
- /**
1190
- * Uploads a chunk of a file to an open upload session
1191
- *
1192
- * API Endpoint: '/files/upload_sessions/:sessionID'
1193
- * Method: PUT
1194
- *
1195
- * @param {string} sessionID - The ID of the upload session to upload to
1196
- * @param {Buffer|string} part - The chunk of the file to upload
1197
- * @param {int} offset - The byte position where the chunk begins in the file
1198
- * @param {int} totalSize - The total size of the file being uploaded
1199
- * @param {Function} [callback] - Passed the part definition if successful
1200
- * @returns {Promise<Object>} A promise resolving to the part object
1201
- */
1202
- Files.prototype.uploadPart = function(sessionID, part, offset, totalSize, callback) {
1203
-
1204
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID);
1205
- var hash = crypto.createHash('sha1').update(part)
1206
- .digest('base64');
1207
-
1208
- var params = {
1209
- headers: {
1210
- 'Content-Type': 'application/octet-stream',
1211
- Digest: `SHA=${hash}`,
1212
- 'Content-Range': `bytes ${offset}-${offset + part.length - 1}/${totalSize}`
1213
- },
1214
- json: false,
1215
- body: part
1216
- };
1217
-
1218
- return this.client.put(apiURL, params)
1219
- .then(response => {
1220
-
1221
- if (response.statusCode !== 200) {
1222
- throw errors.buildUnexpectedResponseError(response);
1223
- }
1224
-
1225
- return JSON.parse(response.body);
1226
- })
1227
- .asCallback(callback);
1228
- };
1229
-
1230
- /**
1231
- * Commit an upload session after all parts have been uploaded, creating the new file
1232
- *
1233
- * API Endpoint: '/files/upload_sessions/:sessionID/commit'
1234
- * Method: POST
1235
- *
1236
- * @param {string} sessionID - The ID of the upload session to commit
1237
- * @param {string} fileHash - The base64-encoded SHA-1 hash of the file being uploaded
1238
- * @param {Object} [options] - Optional parameters set on the created file, can be left null
1239
- * @param {UploadPart[]} [options.parts] The list of uploaded parts to be committed, will be fetched from the API otherwise
1240
- * @param {Function} [callback] - Passed the new file information if successful
1241
- * @returns {Promise<Object>} A promise resolving to the uploaded file object
1242
- */
1243
- Files.prototype.commitUploadSession = function(sessionID, fileHash, options, callback) {
1244
-
1245
- options = options || {};
1246
-
1247
- var userParts;
1248
- if (options.parts) {
1249
- userParts = options.parts;
1250
- delete options.parts;
1251
- }
1252
-
1253
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID, 'commit'),
1254
- params = {
1255
- headers: {
1256
- Digest: `SHA=${fileHash}`
1257
- },
1258
- body: {
1259
- attributes: options
1260
- }
1261
- };
1262
-
1263
- var fetchParts = (offset, fetchedParts) => {
1264
-
1265
- let pagingOptions = {
1266
- limit: 1000,
1267
- offset
1268
- };
1269
-
1270
- return this.getUploadSessionParts(sessionID, pagingOptions)
1271
- .then(data => {
1272
-
1273
- fetchedParts = fetchedParts.concat(data.entries);
1274
-
1275
- if (data.offset + data.entries.length >= data.total_count) {
1276
- return Promise.resolve(fetchedParts);
1277
- }
1278
-
1279
- return fetchParts(offset + data.limit, fetchedParts);
1280
- });
1281
- };
1282
-
1283
- return (userParts ? Promise.resolve(userParts) : fetchParts(0, []))
1284
- .then(parts => {
1285
-
1286
- // Commit the upload with the list of parts
1287
- params.body.parts = parts;
1288
- return this.client.post(apiURL, params);
1289
- }).then(response => {
1290
-
1291
- if (response.statusCode === 201) {
1292
- return response.body;
1293
- }
1294
-
1295
- if (response.statusCode === 202) {
1296
- var retryInterval = response.headers['retry-after'] || 1;
1297
- return Promise.delay(retryInterval * 1000)
1298
- .then(() => {
1299
-
1300
- // Ensure we don't have to fetch parts from the API again on retry
1301
- options = Object.assign({}, options, { parts: params.body.parts });
1302
- return this.commitUploadSession(sessionID, fileHash, options);
1303
- });
1304
- }
1305
-
1306
- throw errors.buildUnexpectedResponseError(response);
1307
- })
1308
- .asCallback(callback);
1309
- };
1310
-
1311
- /**
1312
- * Abort an upload session, discarding any chunks that were uploaded to it
1313
- *
1314
- * API Endpoint: '/files/upload_sessions/:sessionID'
1315
- * Method: DELETE
1316
- *
1317
- * @param {string} sessionID - The ID of the upload session to commit
1318
- * @param {Function} [callback] - Passed nothing if successful, error otherwise
1319
- * @returns {Promise<void>} A promise resolving to nothing
1320
- */
1321
- Files.prototype.abortUploadSession = function(sessionID, callback) {
1322
-
1323
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID);
1324
-
1325
- return this.client.wrapWithDefaultHandler(this.client.del)(apiURL, null, callback);
1326
- };
1327
-
1328
- /**
1329
- * Get a list of all parts that have been uploaded to an upload session
1330
- *
1331
- * API Endpoint: '/files/upload_sessions/:sessionID/parts'
1332
- * Method: GET
1333
- *
1334
- * @param {string} sessionID - The ID of the session to get a list of parts from
1335
- * @param {Object} [options] - Optional parameters, can be left null
1336
- * @param {string} [options.offset] - Paging offset for the list of parts
1337
- * @param {int} [options.limit] - Maximum number of parts to return
1338
- * @param {Function} [callback] - Passed the list of parts if successful
1339
- * @returns {Promise<Object>} A promise resolving to the collection of uploaded parts
1340
- */
1341
- Files.prototype.getUploadSessionParts = function(sessionID, options, callback) {
1342
-
1343
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID, 'parts'),
1344
- params = {
1345
- qs: options
1346
- };
1347
-
1348
- return this.client.wrapWithDefaultHandler(this.client.get)(apiURL, params, callback);
1349
- };
1350
-
1351
- /**
1352
- * Get the status of an upload session, e.g. whether or not is has started or
1353
- * finished committing
1354
- *
1355
- * API Endpoint: '/files/upload_sessions/:sessionID'
1356
- * Method: GET
1357
- *
1358
- * @param {string} sessionID - The ID of the upload session to get the status of
1359
- * @param {Function} [callback] - Passed the session status if successful
1360
- * @returns {Promise<Object>} A promise resolving to the upload session object
1361
- */
1362
- Files.prototype.getUploadSession = function(sessionID, callback) {
1363
-
1364
- var apiURL = this.client._uploadBaseURL + urlPath(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID);
1365
-
1366
- return this.client.wrapWithDefaultHandler(this.client.get)(apiURL, null, callback);
1367
- };
1368
-
1369
- /**
1370
- * Upload a file in chunks, which is generally faster and more reliable for
1371
- * large files.
1372
- *
1373
- * API Endpoint: '/files/upload_sessions'
1374
- * Method: POST
1375
- *
1376
- * @param {string} folderID - The ID of the folder to upload the file to
1377
- * @param {int} size - The size of the file that will be uploaded
1378
- * @param {string} name - The name of the file to be created
1379
- * @param {Buffer|string|Readable} file - The file to upload
1380
- * @param {Object} [options] - Optional parameters for the upload
1381
- * @param {int} [options.parallelism] The number of chunks to upload concurrently
1382
- * @param {int} [options.retryInterval] The amount of time to wait before retrying a failed chunk upload, in ms
1383
- * @param {Object} [options.fileAttributes] Attributes to set on the newly-uploaded file
1384
- * @param {Function} [callback] - Passed the uploader if successful
1385
- * @returns {Promise<ChunkedUploader>} A promise resolving to the chunked uploader
1386
- */
1387
- Files.prototype.getChunkedUploader = function(folderID, size, name, file, options, callback) {
1388
-
1389
- if (file instanceof Readable) {
1390
- // Need to pause the stream immediately to prevent certain libraries,
1391
- // e.g. request from placing the stream into flowing mode and consuming bytes
1392
- file.pause();
1393
- }
1394
-
1395
- return this.createUploadSession(folderID, size, name)
1396
- .then(sessionInfo => new ChunkedUploader(this.client, sessionInfo, file, size, options))
1397
- .asCallback(callback);
1398
- };
1399
-
1400
- /**
1401
- * Upload a new file version in chunks, which is generally faster and more
1402
- * reliable for large files.
1403
- *
1404
- * API Endpoint: '/files/:fileID/upload_sessions'
1405
- * Method: POST
1406
- *
1407
- * @param {string} fileID - The ID of the file to upload a new version of
1408
- * @param {int} size - The size of the file that will be uploaded
1409
- * @param {Buffer|string|Readable} file - The file to upload
1410
- * @param {Object} [options] - Optional parameters for the upload
1411
- * @param {int} [options.parallelism] The number of chunks to upload concurrently
1412
- * @param {int} [options.retryInterval] The amount of time to wait before retrying a failed chunk upload, in ms
1413
- * @param {Object} [options.fileAttributes] Attributes to set on the updated file object
1414
- * @param {Function} [callback] - Passed the uploader if successful
1415
- * @returns {Promise<ChunkedUploader>} A promise resolving to the chunked uploader
1416
- */
1417
- Files.prototype.getNewVersionChunkedUploader = function(fileID, size, file, options, callback) {
1418
-
1419
- if (file instanceof Readable) {
1420
- // Need to pause the stream immediately to prevent certain libraries,
1421
- // e.g. request from placing the stream into flowing mode and consuming bytes
1422
- file.pause();
1423
- }
1424
-
1425
- return this.createNewVersionUploadSession(fileID, size)
1426
- .then(sessionInfo => new ChunkedUploader(this.client, sessionInfo, file, size, options))
1427
- .asCallback(callback);
1428
- };
1429
-
1430
- /**
1431
- * Requests collaborations on a given file.
1432
- *
1433
- * API Endpoint: '/files/:fileID/collaborations'
1434
- * Method: GET
1435
- *
1436
- * @param {string} fileID - Box ID of the file being requested
1437
- * @param {Object} [options] - Additional options. Can be left null in most cases.
1438
- * @param {int} [options.limit] - The maximum number of collaborations to return
1439
- * @param {int} [options.offset] - Paging parameter for the collaborations collection
1440
- * @param {string} [options.fields] - Comma-separated list of fields to return on the collaboration objects
1441
- * @param {Function} [callback] - Passed the collaborations if successful, error otherwise
1442
- * @returns {Promise<Object>} A promise resolving to the collection of collaborations on the file
1443
- */
1444
- Files.prototype.getCollaborations = function(fileID, options, callback) {
1445
- var params = {
1446
- qs: options
1447
- };
1448
- var apiPath = urlPath(BASE_PATH, fileID, '/collaborations');
1449
- return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
1450
- };
1451
-
128
+ var Files = /** @class */ (function () {
129
+ function Files(client) {
130
+ // Attach the client, for making API calls
131
+ this.client = client;
132
+ }
133
+ /**
134
+ * Requests a file object with the given ID.
135
+ *
136
+ * API Endpoint: '/files/:fileID'
137
+ * Method: GET
138
+ *
139
+ * @param {string} fileID - Box ID of the file being requested
140
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
141
+ * @param {Function} [callback] - Passed the file information if it was acquired successfully
142
+ * @returns {Promise<Object>} A promise resolving to the file object
143
+ */
144
+ Files.prototype.get = function (fileID, options, callback) {
145
+ var params = {
146
+ qs: options,
147
+ };
148
+ var apiPath = url_path_1.default(BASE_PATH, fileID);
149
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
150
+ };
151
+ /**
152
+ * Requests a download URL for a given file.
153
+ *
154
+ * API Endpoint: '/files/:fileID/content'
155
+ * Method: GET
156
+ * Special Expected Responses:
157
+ * 202 ACCEPTED - Download isn't available yet. Returns an error.
158
+ * 302 FOUND - Download is available. A Download URL is returned.
159
+ *
160
+ * @param {string} fileID - Box ID of the file being requested
161
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
162
+ * @param {Function} [callback] - Passed the download URL if request was successful.
163
+ * @returns {Promise<string>} A promise resolving to the file's download URL
164
+ */
165
+ Files.prototype.getDownloadURL = function (fileID, options, callback) {
166
+ var params = {
167
+ qs: options,
168
+ };
169
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/content');
170
+ // Handle Special API Response
171
+ return this.client
172
+ .get(apiPath, params)
173
+ .then(function (response /* FIXME */) {
174
+ switch (response.statusCode) {
175
+ // 302 - Found
176
+ // No data returned, but the location header points to a download link for that file.
177
+ case http_status_1.default.FOUND:
178
+ return response.headers.location;
179
+ // 202 - Download isn't ready yet.
180
+ case http_status_1.default.ACCEPTED:
181
+ throw errors_1.default.buildResponseError(response, 'Download not ready at this time');
182
+ // Unexpected Response
183
+ default:
184
+ throw errors_1.default.buildUnexpectedResponseError(response);
185
+ }
186
+ })
187
+ .asCallback(callback);
188
+ };
189
+ /**
190
+ * Requests a Readable Stream for the given file ID.
191
+ *
192
+ * API Endpoint: '/files/:fileID/content'
193
+ * Method: GET
194
+ * Special Expected Responses:
195
+ * 202 ACCEPTED - Download isn't available yet. Returns an error.
196
+ * 302 FOUND - Download is available. A Download stream is returned.
197
+ *
198
+ * @param {string} fileID - Box ID of the file being requested
199
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
200
+ * @param {string} [options.version] - ID of the version of this file to download
201
+ * @param {int[]} [options.byteRange] - starting and ending bytes of the file to read, e.g. [0, 99] to read the first 100 bytes
202
+ * @param {Function} [callback] - passed the readable stream if request was successful
203
+ * @returns {Promise<Readable>} A promise resolving for the file stream
204
+ */
205
+ Files.prototype.getReadStream = function (fileID, options, callback) {
206
+ var _this = this;
207
+ options = options || {};
208
+ var downloadStreamOptions = {
209
+ streaming: true,
210
+ headers: {},
211
+ };
212
+ if (options.byteRange) {
213
+ var range = options.byteRange;
214
+ delete options.byteRange;
215
+ downloadStreamOptions.headers.Range = "bytes=" + range[0] + "-" + range[1];
216
+ }
217
+ // Get the download URL to download from
218
+ return (this.getDownloadURL(fileID, options)
219
+ // Return a read stream to download the file
220
+ .then(function (url) { return _this.client.get(url, downloadStreamOptions); })
221
+ .asCallback(callback));
222
+ };
223
+ /**
224
+ * Requests a Thumbnail for a given file.
225
+ *
226
+ * API Endpoint: '/files/:fileID/thumbnail.png'
227
+ * Method: GET
228
+ * Special Expected Responses:
229
+ * 200 OK - Thumbnail available. Returns a thumbnail file.
230
+ * 202 ACCEPTED - Thumbnail isn't available yet. Returns a `location` URL for a generic placeholder thumbnail.
231
+ * 302 FOUND - Unable to generate thumbnail. Returns a `location` URL for a generic placeholder thumbnail.
232
+ *
233
+ * @param {string} fileID - Box ID of the file being requested
234
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
235
+ * @param {Function} [callback] - Passed the thumbnail file or the URL to a placeholder thumbnail if successful.
236
+ * @returns {Promise<Object>} A promise resolving to the thumbnail information
237
+ */
238
+ Files.prototype.getThumbnail = function (fileID, options, callback) {
239
+ var params = {
240
+ qs: options,
241
+ json: false,
242
+ };
243
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/thumbnail.png');
244
+ // Handle Special API Response
245
+ return this.client
246
+ .get(apiPath, params)
247
+ .then(function (response /* FIXME */) {
248
+ switch (response.statusCode) {
249
+ // 202 - Thumbnail will be generated, but is not ready yet
250
+ // 302 - Thumbnail can not be generated
251
+ // return the url for a thumbnail placeholder
252
+ case http_status_1.default.ACCEPTED:
253
+ case http_status_1.default.FOUND:
254
+ return {
255
+ statusCode: response.statusCode,
256
+ location: response.headers.location,
257
+ };
258
+ // 200 - Thumbnail image recieved
259
+ // return the thumbnail file
260
+ case http_status_1.default.OK:
261
+ return {
262
+ statusCode: response.statusCode,
263
+ file: response.body,
264
+ };
265
+ // Unexpected Response
266
+ default:
267
+ throw errors_1.default.buildUnexpectedResponseError(response);
268
+ }
269
+ })
270
+ .asCallback(callback);
271
+ };
272
+ /**
273
+ * Gets the comments on a file.
274
+ *
275
+ * API Endpoint: '/files/:fileID/comments'
276
+ * Method: GET
277
+ *
278
+ * @param {string} fileID - Box file id of the file
279
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
280
+ * @param {Function} [callback] - passed the file comments if they were successfully acquired
281
+ * @returns {Promise<Object>} A promise resolving to the collection of comments
282
+ */
283
+ Files.prototype.getComments = function (fileID, options, callback) {
284
+ var params = {
285
+ qs: options,
286
+ };
287
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/comments');
288
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
289
+ };
290
+ /**
291
+ * Update some information about a given file.
292
+ *
293
+ * API Endpoint: '/files/:fileID'
294
+ * Method: PUT
295
+ *
296
+ * @param {string} fileID - Box ID of the file being requested
297
+ * @param {Object} updates - File fields to update
298
+ * @param {string} [updates.etag] Only apply the updates if the file etag matches
299
+ * @param {Function} [callback] - Passed the updated file information if it was acquired successfully
300
+ * @returns {Promise<Object>} A promise resolving to the update file object
301
+ */
302
+ Files.prototype.update = function (fileID, updates, callback) {
303
+ var params = {
304
+ body: updates,
305
+ };
306
+ if (updates && updates.etag) {
307
+ params.headers = {
308
+ 'If-Match': updates.etag,
309
+ };
310
+ delete updates.etag;
311
+ }
312
+ var apiPath = url_path_1.default(BASE_PATH, fileID);
313
+ return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
314
+ };
315
+ /**
316
+ * Add a file to a given collection
317
+ *
318
+ * API Endpoint: '/files/:fileID'
319
+ * Method: PUT
320
+ *
321
+ * @param {string} fileID - The file to add to the collection
322
+ * @param {string} collectionID - The collection to add the file to
323
+ * @param {Function} [callback] - Passed the updated file if successful, error otherwise
324
+ * @returns {Promise<Object>} A promise resolving to the updated file object
325
+ */
326
+ Files.prototype.addToCollection = function (fileID, collectionID, callback) {
327
+ var _this = this;
328
+ return this.get(fileID, { fields: 'collections' })
329
+ .then(function (data) {
330
+ var collections = data.collections || [];
331
+ // Convert to correct format
332
+ collections = collections.map(function (c /* FIXME */) { return ({ id: c.id }); });
333
+ if (!collections.find(function (c /* FIXME */) { return c.id === collectionID; })) {
334
+ collections.push({ id: collectionID });
335
+ }
336
+ return _this.update(fileID, { collections: collections });
337
+ })
338
+ .asCallback(callback);
339
+ };
340
+ /**
341
+ * Remove a file from a given collection
342
+ *
343
+ * API Endpoint: '/files/:fileID'
344
+ * Method: PUT
345
+ *
346
+ * @param {string} fileID - The file to remove from the collection
347
+ * @param {string} collectionID - The collection to remove the file from
348
+ * @param {Function} [callback] - Passed the updated file if successful, error otherwise
349
+ * @returns {Promise<Object>} A promise resolving to the updated file object
350
+ */
351
+ Files.prototype.removeFromCollection = function (fileID, collectionID, callback) {
352
+ var _this = this;
353
+ return this.get(fileID, { fields: 'collections' })
354
+ .then(function (data /* FIXME */) {
355
+ var collections = data.collections || [];
356
+ // Convert to correct object format and remove the specified collection
357
+ collections = collections
358
+ .map(function (c /* FIXME */) { return ({ id: c.id }); })
359
+ .filter(function (c /* FIXME */) { return c.id !== collectionID; });
360
+ return _this.update(fileID, { collections: collections });
361
+ })
362
+ .asCallback(callback);
363
+ };
364
+ /**
365
+ * Move a file into a new parent folder.
366
+ *
367
+ * API Endpoint: '/files/:fileID'
368
+ * Method: PUT
369
+ *
370
+ * @param {string} fileID - The Box ID of the file being requested
371
+ * @param {string} newParentID - The Box ID for the new parent folder. '0' to move to All Files.
372
+ * @param {Function} [callback] - Passed the updated file information if it was acquired successfully
373
+ * @returns {Promise<Object>} A promise resolving to the updated file object
374
+ */
375
+ Files.prototype.move = function (fileID, newParentID, callback) {
376
+ var params = {
377
+ body: {
378
+ parent: {
379
+ id: newParentID,
380
+ },
381
+ },
382
+ };
383
+ var apiPath = url_path_1.default(BASE_PATH, fileID);
384
+ return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
385
+ };
386
+ /**
387
+ * Copy a file into a new folder.
388
+ *
389
+ * API Endpoint: '/files/:fileID/copy
390
+ * Method: POST
391
+ *
392
+ * @param {string} fileID - The Box ID of the file being requested
393
+ * @param {string} newParentID - The Box ID for the new parent folder. '0' to copy to All Files.
394
+ * @param {Object} [options] - Optional parameters for the copy operation, can be left null in most cases
395
+ * @param {string} [options.name] - A new name to use if there is an identically-named item in the new parent folder
396
+ * @param {Function} [callback] - passed the new file info if call was successful
397
+ * @returns {Promise<Object>} A promise resolving to the new file object
398
+ */
399
+ Files.prototype.copy = function (fileID, newParentID, options, callback) {
400
+ // @NOTE(mwiller) 2016-10-25: Shuffle arguments to maintain backward compatibility
401
+ // This can be removed at the v2.0 update
402
+ if (typeof options === 'function') {
403
+ callback = options;
404
+ options = {};
405
+ }
406
+ options = options || {};
407
+ options.parent = {
408
+ id: newParentID,
409
+ };
410
+ var params = {
411
+ body: options,
412
+ };
413
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/copy');
414
+ return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
415
+ };
416
+ /**
417
+ * Delete a given file.
418
+ *
419
+ * API Endpoint: '/files/:fileID'
420
+ * Method: DELETE
421
+ *
422
+ * @param {string} fileID - Box ID of the file being requested
423
+ * @param {Object} [options] Optional parameters
424
+ * @param {string} [options.etag] Only delete the file if the etag value matches
425
+ * @param {Function} [callback] - Empty response body passed if successful.
426
+ * @returns {Promise<void>} A promise resolving to nothing
427
+ */
428
+ Files.prototype.delete = function (fileID, options, callback) {
429
+ // Switch around arguments if necessary for backwards compatibility
430
+ if (typeof options === 'function') {
431
+ callback = options;
432
+ options = {};
433
+ }
434
+ var params = {};
435
+ if (options && options.etag) {
436
+ params.headers = {
437
+ 'If-Match': options.etag,
438
+ };
439
+ }
440
+ var apiPath = url_path_1.default(BASE_PATH, fileID);
441
+ return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, params, callback);
442
+ };
443
+ /**
444
+ * Get preflight information for a new file upload. Without any file data,
445
+ * this will return an upload URL and token to be used when uploading the file.
446
+ * Using this upload URL will allow for the fastest upload, and the one-time
447
+ * token can be passed to a worker or other client to actually perform the
448
+ * upload with. If file data (e.g. size, parent, name) is passed, it will be
449
+ * validated as if the actual file were being uploaded. This enables checking
450
+ * of preconditions such as name uniqueness and available storage space before
451
+ * attempting a large file upload.
452
+ *
453
+ * API Endpoint: '/files/content'
454
+ * Method: OPTIONS
455
+ *
456
+ * @param {string} parentFolderID - The id of the parent folder to upload to
457
+ * @param {Object} [fileData] - Optional data about the file to be uploaded
458
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
459
+ * @param {Function} [callback] - Called with upload data if successful, or err if the upload would not succeed
460
+ * @returns {Promise<Object>} A promise resolving to the upload data
461
+ */
462
+ Files.prototype.preflightUploadFile = function (parentFolderID, fileData, options, callback) {
463
+ var params = {
464
+ body: {
465
+ parent: {
466
+ id: parentFolderID,
467
+ },
468
+ },
469
+ qs: options,
470
+ };
471
+ if (fileData) {
472
+ Object.assign(params.body, fileData);
473
+ }
474
+ var apiPath = url_path_1.default(BASE_PATH, '/content');
475
+ return this.client.wrapWithDefaultHandler(this.client.options)(apiPath, params, callback);
476
+ };
477
+ /**
478
+ * Get preflight information for a file version upload. Without any file data,
479
+ * this will return an upload URL and token to be used when uploading the file.
480
+ * Using this upload URL will allow for the fastest upload, and the one-time
481
+ * token can be passed to a worker or other client to actually perform the
482
+ * upload with. If file data (e.g. size, parent, name) is passed, it will be
483
+ * validated as if the actual file were being uploaded. This enables checking
484
+ * of preconditions such as name uniqueness and available storage space before
485
+ * attempting a large file upload.
486
+ *
487
+ * API Endpoint: '/files/:fileID/content'
488
+ * Method: OPTIONS
489
+ *
490
+ * @param {string} fileID - The file ID to which a new version will be uploaded
491
+ * @param {Object} [fileData] - Optional data about the file to be uploaded
492
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
493
+ * @param {Function} [callback] - Called with upload data if successful, or err if the upload would not succeed
494
+ * @returns {Promise<Object>} A promise resolving to the upload data
495
+ */
496
+ Files.prototype.preflightUploadNewFileVersion = function (fileID, fileData, options, callback) {
497
+ var params = {
498
+ qs: options,
499
+ };
500
+ if (fileData) {
501
+ params.body = fileData;
502
+ }
503
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/content');
504
+ return this.client.wrapWithDefaultHandler(this.client.options)(apiPath, params, callback);
505
+ };
506
+ /**
507
+ * If there are previous versions of this file, this method can be used to promote one of the older
508
+ * versions to the top of the stack. This actually mints a copy of the old version and puts it on
509
+ * the top of the versions stack. The file will have the exact same contents, the same SHA1/etag,
510
+ * and the same name as the original. Other properties such as comments do not get updated to their former values.
511
+ *
512
+ * API Endpoint: '/files/:fileID/versions/current'
513
+ * Method: POST
514
+ *
515
+ * @param {string} fileID - The file ID which version will be promoted
516
+ * @param {string} versionID - The ID of the file_version that you want to make current
517
+ * @param {Function} [callback] - Passed the promoted file version information if successful, error otherwise
518
+ * @returns {Promise<Object>} A promise resolving to the promoted file version
519
+ */
520
+ Files.prototype.promoteVersion = function (fileID, versionID, callback) {
521
+ var apiPath = url_path_1.default(BASE_PATH, fileID, VERSIONS_SUBRESOURCE, '/current'), params = {
522
+ body: {
523
+ type: 'file_version',
524
+ id: versionID,
525
+ },
526
+ };
527
+ return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
528
+ };
529
+ /**
530
+ * Uploads a new file. Unlike non-upload methods, this method will not perform any retries.
531
+ * This method currently does not support any optional parameters such as contentModifiedAt.
532
+ *
533
+ * API Endpoint: '/files/content'
534
+ * Method: POST
535
+ *
536
+ * @param {string} parentFolderID - the id of the parent folder to upload to
537
+ * @param {string} filename - the file name that the uploaded file should have
538
+ * @param {string|Buffer|ReadStream} content - the content of the file. It can be a string, a Buffer, or a read stream
539
+ * (like that returned by fs.createReadStream()).
540
+ * @param {Object} [options] - Optional parameters
541
+ * @param {string} [options.content_created_at] - RFC 3339 timestamp when the file was created
542
+ * @param {string} [options.content_modified_at] - RFC 3339 timestamp when the file was last modified
543
+ * @param {int} [options.content_length] - Optional length of the content. Required if content is a read stream of any type other than fs stream.
544
+ * @param {Function} [callback] - called with data about the upload if successful, or an error if the
545
+ * upload failed
546
+ * @returns {Promise<Object>} A promise resolving to the uploaded file
547
+ */
548
+ Files.prototype.uploadFile = function (parentFolderID, filename, content, options, callback) {
549
+ // Shuffle around optional parameter
550
+ if (typeof options === 'function') {
551
+ callback = options;
552
+ options = {};
553
+ }
554
+ var formOptions = {};
555
+ if (options && options.hasOwnProperty('content_length')) {
556
+ formOptions.knownLength = options.content_length;
557
+ // Delete content_length from options so it's not added to the attributes of the form
558
+ delete options.content_length;
559
+ }
560
+ var apiPath = url_path_1.default(BASE_PATH, '/content'), multipartFormData = {
561
+ attributes: createFileMetadataFormData(parentFolderID, filename, options),
562
+ content: createFileContentFormData(content, formOptions),
563
+ };
564
+ return this.client.wrapWithDefaultHandler(this.client.upload)(apiPath, null, multipartFormData, callback);
565
+ };
566
+ /**
567
+ * Uploads a new version of a file. Unlike non-upload methods, this method will not perform any retries.
568
+ * This method currently does not support any optional parameters such as contentModifiedAt.
569
+ *
570
+ * API Endpoint: '/files/:fileID/content'
571
+ * Method: POST
572
+ *
573
+ * @param {string} fileID - the id of the file to upload a new version of
574
+ * @param {string|Buffer|Stream} content - the content of the file. It can be a string, a Buffer, or a read stream
575
+ * (like that returned by fs.createReadStream()).
576
+ * @param {Object} [options] - Optional parameters
577
+ * @param {string} [options.content_modified_at] - RFC 3339 timestamp when the file was last modified
578
+ * @param {string} [options.name] - A new name for the file
579
+ * @param {int} [options.content_length] - Optional length of the content. Required if content is a read stream of any type other than fs stream.
580
+ * @param {Function} [callback] - called with data about the upload if successful, or an error if the
581
+ * upload failed
582
+ * @returns {Promise<Object>} A promise resolving to the uploaded file
583
+ */
584
+ Files.prototype.uploadNewFileVersion = function (fileID, content, options, callback) {
585
+ // Shuffle around optional parameter
586
+ if (typeof options === 'function') {
587
+ callback = options;
588
+ options = {};
589
+ }
590
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/content'), multipartFormData = {};
591
+ var formOptions = {};
592
+ if (options) {
593
+ if (options.hasOwnProperty('content_length')) {
594
+ formOptions.knownLength = options.content_length;
595
+ // Delete content_length from options so it's not added to the attributes of the form
596
+ delete options.content_length;
597
+ }
598
+ multipartFormData.attributes = JSON.stringify(options);
599
+ }
600
+ multipartFormData.content = createFileContentFormData(content, formOptions);
601
+ return this.client.wrapWithDefaultHandler(this.client.upload)(apiPath, null, multipartFormData, callback);
602
+ };
603
+ /**
604
+ * Retrieves all metadata associated with a file.
605
+ *
606
+ * API Endpoint: '/files/:fileID/metadata'
607
+ * Method: GET
608
+ *
609
+ * @param {string} fileID - the ID of the file to get metadata for
610
+ * @param {Function} [callback] - called with an array of metadata when successful
611
+ * @returns {Promise<Object>} A promise resolving to a collection of metadata on the file
612
+ */
613
+ Files.prototype.getAllMetadata = function (fileID, callback) {
614
+ var apiPath = url_path_1.default(BASE_PATH, fileID, 'metadata');
615
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, null, callback);
616
+ };
617
+ /**
618
+ * Retrieve a single metadata template instance for a file.
619
+ *
620
+ * API Endpoint: '/files/:fileID/metadata/:scope/:template'
621
+ * Method: GET
622
+ *
623
+ * @param {string} fileID - The ID of the file to retrive the metadata of
624
+ * @param {string} scope - The scope of the metadata template, e.g. "global"
625
+ * @param {string} template - The metadata template to retrieve
626
+ * @param {Function} [callback] - Passed the metadata template if successful
627
+ * @returns {Promise<Object>} A promise resolving to the metadata template
628
+ */
629
+ Files.prototype.getMetadata = function (fileID, scope, template, callback) {
630
+ var apiPath = url_path_1.default(BASE_PATH, fileID, 'metadata', scope, template);
631
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, null, callback);
632
+ };
633
+ /**
634
+ * Adds metadata to a file. Metadata must either match a template schema or
635
+ * be placed into the unstructured "properties" template in global scope.
636
+ *
637
+ * API Endpoint: '/files/:fileID/metadata/:scope/:template'
638
+ * Method: POST
639
+ *
640
+ * @param {string} fileID - The ID of the file to add metadata to
641
+ * @param {string} scope - The scope of the metadata template, e.g. "enterprise"
642
+ * @param {string} template - The metadata template schema to add
643
+ * @param {Object} data - Key/value pairs tp add as metadata
644
+ * @param {Function} [callback] - Called with error if unsuccessful
645
+ * @returns {Promise<Object>} A promise resolving to the new metadata
646
+ */
647
+ Files.prototype.addMetadata = function (fileID, scope, template, data, callback) {
648
+ var apiPath = url_path_1.default(BASE_PATH, fileID, 'metadata', scope, template), params = {
649
+ body: data,
650
+ };
651
+ return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
652
+ };
653
+ /**
654
+ * Updates a metadata template instance with JSON Patch-formatted data.
655
+ *
656
+ * API Endpoint: '/files/:fileID/metadata/:scope/:template'
657
+ * Method: PUT
658
+ *
659
+ * @param {string} fileID - The file to update metadata for
660
+ * @param {string} scope - The scope of the template to update
661
+ * @param {string} template - The template to update
662
+ * @param {Object} patch - The patch data
663
+ * @param {Function} [callback] - Called with updated metadata if successful
664
+ * @returns {Promise<Object>} A promise resolving to the updated metadata
665
+ */
666
+ Files.prototype.updateMetadata = function (fileID, scope, template, patch, callback) {
667
+ var apiPath = url_path_1.default(BASE_PATH, fileID, 'metadata', scope, template), params = {
668
+ body: patch,
669
+ headers: {
670
+ 'Content-Type': 'application/json-patch+json',
671
+ },
672
+ };
673
+ return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
674
+ };
675
+ /**
676
+ * Sets metadata on a file, overwriting any metadata that exists for the provided keys.
677
+ *
678
+ * @param {string} fileID - The file to set metadata on
679
+ * @param {string} scope - The scope of the metadata template
680
+ * @param {string} template - The key of the metadata template
681
+ * @param {Object} metadata - The metadata to set
682
+ * @param {Function} [callback] - Called with updated metadata if successful
683
+ * @returns {Promise<Object>} A promise resolving to the updated metadata
684
+ */
685
+ Files.prototype.setMetadata = function (fileID, scope, template, metadata, callback) {
686
+ var _this = this;
687
+ return this.addMetadata(fileID, scope, template, metadata)
688
+ .catch(function (err /* FIXME */) {
689
+ if (err.statusCode !== 409) {
690
+ throw err;
691
+ }
692
+ // Metadata already exists on the file; update instead
693
+ var updates = Object.keys(metadata).map(function (key) { return ({
694
+ op: 'add',
695
+ path: "/" + key,
696
+ value: metadata[key],
697
+ }); });
698
+ return _this.updateMetadata(fileID, scope, template, updates);
699
+ })
700
+ .asCallback(callback);
701
+ };
702
+ /**
703
+ * Deletes a metadata template from a file.
704
+ *
705
+ * API Endpoint: '/files/:fileID/metadata/:scope/:template'
706
+ * Method: DELETE
707
+ *
708
+ * @param {string} fileID - The ID of the file to remove metadata from
709
+ * @param {string} scope - The scope of the metadata template
710
+ * @param {string} template - The template to remove from the file
711
+ * @param {Function} [callback] - Called with nothing if successful, error otherwise
712
+ * @returns {Promise<void>} A promise resolving to nothing
713
+ */
714
+ Files.prototype.deleteMetadata = function (fileID, scope, template, callback) {
715
+ var apiPath = url_path_1.default(BASE_PATH, fileID, 'metadata', scope, template);
716
+ return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, null, callback);
717
+ };
718
+ /**
719
+ * Permanently deletes an item that is in the trash. The item will no longer exist in Box. This action cannot be undone.
720
+ *
721
+ * API Endpoint: '/files/:fileID/trash'
722
+ * Method: DELETE
723
+ *
724
+ * @param {string} fileID - The ID of the file to remove metadata from
725
+ * @param {Object} [options] Optional parameters
726
+ * @param {string} [options.etag] Only delete the file if the etag matches
727
+ * @param {Function} [callback] - Called with nothing if successful, error otherwise
728
+ * @returns {Promise<void>} A promise resolving to nothing
729
+ */
730
+ Files.prototype.deletePermanently = function (fileID, options, callback) {
731
+ if (typeof options === 'function') {
732
+ callback = options;
733
+ options = {};
734
+ }
735
+ var params = {};
736
+ if (options && options.etag) {
737
+ params.headers = {
738
+ 'If-Match': options.etag,
739
+ };
740
+ }
741
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/trash');
742
+ return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, params, callback);
743
+ };
744
+ /**
745
+ * Retrieves a file that has been moved to the trash.
746
+ *
747
+ * API Endpoint: '/files/:fileID/trash'
748
+ * Method: GET
749
+ *
750
+ * @param {string} fileID - The ID of the file being requested
751
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
752
+ * @param {Function} [callback] - Passed the trashed file information if successful, error otherwise
753
+ * @returns {Promise<Object>} A promise resolving to the trashed file
754
+ */
755
+ Files.prototype.getTrashedFile = function (fileID, options, callback) {
756
+ var params = {
757
+ qs: options,
758
+ };
759
+ var apiPath = url_path_1.default(BASE_PATH, fileID, 'trash');
760
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
761
+ };
762
+ /**
763
+ * Retrieves all of the tasks for given file.
764
+ *
765
+ * API Endpoint: '/files/:fileID/tasks'
766
+ * Method: GET
767
+ *
768
+ * @param {string} fileID - The ID of the file to get tasks for
769
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
770
+ * @param {Function} [callback] - Passed the file tasks if successful, error otherwise
771
+ * @returns {Promise<Object>} A promise resolving to a collections of tasks on the file
772
+ */
773
+ Files.prototype.getTasks = function (fileID, options, callback) {
774
+ var params = {
775
+ qs: options,
776
+ };
777
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/tasks');
778
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
779
+ };
780
+ /**
781
+ * Used to retrieve an expiring URL for creating an embedded preview session.
782
+ * The URL will expire after 60 seconds and the preview session will expire after 60 minutes.
783
+ *
784
+ * API Endpoint: '/files/:fileID?fields=expiring_embed_link'
785
+ * Method: GET
786
+ *
787
+ * @param {string} fileID - The ID of the file to generate embed link for
788
+ * @param {Function} [callback] - Passed with the embed link if successful, error otherwise
789
+ * @returns {Promise<string>} A promise resolving to the file embed link URL
790
+ */
791
+ Files.prototype.getEmbedLink = function (fileID, callback) {
792
+ var params = {
793
+ qs: {
794
+ fields: 'expiring_embed_link',
795
+ },
796
+ };
797
+ var apiPath = url_path_1.default(BASE_PATH, fileID);
798
+ return this.client
799
+ .get(apiPath, params)
800
+ .then(function (response /* FIXME */) {
801
+ if (response.statusCode !== http_status_1.default.OK) {
802
+ throw errors_1.default.buildUnexpectedResponseError(response);
803
+ }
804
+ return response.body.expiring_embed_link.url;
805
+ })
806
+ .asCallback(callback);
807
+ };
808
+ /**
809
+ * Locks a file.
810
+ *
811
+ * API Endpoint: '/files/:fileID'
812
+ * Method: PUT
813
+ *
814
+ * @param {string} fileID - The ID of the file to lock
815
+ * @param {Object} [options] - Optional parameters, can be left null in most cases
816
+ * @param {?string} [options.expires_at] - The time the lock expires
817
+ * @param {boolean} [options.is_download_prevented] - Whether or not the file can be downloaded while locked
818
+ * @param {Function} [callback] - Passed with the locked file information if successful, error otherwise
819
+ * @returns {Promise<Object>} A promise resolving to the locked file object
820
+ */
821
+ Files.prototype.lock = function (fileID, options, callback) {
822
+ var apiPath = url_path_1.default(BASE_PATH, fileID), params = {
823
+ body: {
824
+ lock: {
825
+ type: LockType.LOCK,
826
+ },
827
+ },
828
+ };
829
+ Object.assign(params.body.lock, options);
830
+ return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
831
+ };
832
+ /**
833
+ * Unlocks a file.
834
+ *
835
+ * API Endpoint: '/files/:fileID'
836
+ * Method: PUT
837
+ *
838
+ * @param {string} fileID - The ID of the file to unlock
839
+ * @param {Function} [callback] - Passed with the unlocked file information if successful, error otherwise
840
+ * @returns {Promise<Object>} A promise resolving to the unlocked file object
841
+ */
842
+ Files.prototype.unlock = function (fileID, callback) {
843
+ var apiPath = url_path_1.default(BASE_PATH, fileID), params = {
844
+ body: {
845
+ lock: null,
846
+ },
847
+ };
848
+ return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
849
+ };
850
+ /**
851
+ * Restores an item that has been moved to the trash. Default behavior is to
852
+ * restore the item to the folder it was in before it was moved to the trash.
853
+ * If that parent folder no longer exists or if there is now an item with the
854
+ * same name in that parent folder, the new parent folder and/or new name will
855
+ * need to be included in the request.
856
+ *
857
+ * API Endpoint: '/files/:fileID'
858
+ * Method: POST
859
+ *
860
+ * @param {string} fileID - The ID of the file to restore
861
+ * @param {Object} [options] - Optional parameters, can be left null in most cases
862
+ * @param {string} [options.name] - The new name for this item
863
+ * @param {string} [options.parent_id] - The new parent folder for this item
864
+ * @param {Function} [callback] - Called with item information if successful, error otherwise
865
+ * @returns {Promise<Object>} A promise resolving to the restored file object
866
+ */
867
+ Files.prototype.restoreFromTrash = function (fileID, options, callback) {
868
+ // Set up the parent_id parameter
869
+ if (options && options.parent_id) {
870
+ options.parent = {
871
+ id: options.parent_id,
872
+ };
873
+ delete options.parent_id;
874
+ }
875
+ var apiPath = url_path_1.default(BASE_PATH, fileID), params = {
876
+ body: options || {},
877
+ };
878
+ return this.client.wrapWithDefaultHandler(this.client.post)(apiPath, params, callback);
879
+ };
880
+ /**
881
+ * If there are previous versions of this file, this method can be used to retrieve information
882
+ * about the older versions.
883
+ *
884
+ * API Endpoint: '/files/:fileID/versions'
885
+ * Method: GET
886
+ *
887
+ * @param {string} fileID - The ID of the file to view version for
888
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
889
+ * @param {Function} [callback] - Passed a list of previous file versions if successful, error otherwise
890
+ * @returns {Promise<Object>} A promise resolving to the collection of file versions
891
+ */
892
+ Files.prototype.getVersions = function (fileID, options, callback) {
893
+ var apiPath = url_path_1.default(BASE_PATH, fileID, VERSIONS_SUBRESOURCE), params = {
894
+ qs: options,
895
+ };
896
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
897
+ };
898
+ /**
899
+ * Used to retrieve the watermark for a corresponding Box file.
900
+ *
901
+ * API Endpoint: '/files/:fileID/watermark'
902
+ * Method: GET
903
+ *
904
+ * @param {string} fileID - The Box ID of the file to get watermark for
905
+ * @param {Object} [options] - Additional options for the request. Can be left null in most cases.
906
+ * @param {Function} [callback] - Passed the watermark information if successful, error otherwise
907
+ * @returns {Promise<Object>} A promise resolving to the watermark info
908
+ */
909
+ Files.prototype.getWatermark = function (fileID, options, callback) {
910
+ var apiPath = url_path_1.default(BASE_PATH, fileID, WATERMARK_SUBRESOURCE), params = {
911
+ qs: options,
912
+ };
913
+ return this.client
914
+ .get(apiPath, params)
915
+ .then(function (response /* FIXME */) {
916
+ if (response.statusCode !== 200) {
917
+ throw errors_1.default.buildUnexpectedResponseError(response);
918
+ }
919
+ return response.body.watermark;
920
+ })
921
+ .asCallback(callback);
922
+ };
923
+ /**
924
+ * Used to apply or update the watermark for a corresponding Box file.
925
+ *
926
+ * API Endpoint: '/files/:fileID/watermark'
927
+ * Method: PUT
928
+ *
929
+ * @param {string} fileID - The Box ID of the file to update watermark for
930
+ * @param {Object} [options] - Optional parameters, can be left null
931
+ * @param {Function} [callback] - Passed the watermark information if successful, error otherwise
932
+ * @returns {Promise<Object>} A promise resolving to the watermark info
933
+ */
934
+ Files.prototype.applyWatermark = function (fileID, options, callback) {
935
+ var apiPath = url_path_1.default(BASE_PATH, fileID, WATERMARK_SUBRESOURCE), params = {
936
+ body: {
937
+ watermark: {
938
+ imprint: 'default', // Currently the API only supports default imprint
939
+ },
940
+ },
941
+ };
942
+ Object.assign(params.body.watermark, options);
943
+ return this.client.wrapWithDefaultHandler(this.client.put)(apiPath, params, callback);
944
+ };
945
+ /**
946
+ * Used to remove the watermark for a corresponding Box file.
947
+ *
948
+ * API Endpoint: '/files/:fileID/watermark'
949
+ * Method: DELETE
950
+ *
951
+ * @param {string} fileID - The Box ID of the file to remove watermark from
952
+ * @param {Function} [callback] - Empty response body passed if successful, error otherwise
953
+ * @returns {Promise<void>} A promise resolving to nothing
954
+ */
955
+ Files.prototype.removeWatermark = function (fileID, callback) {
956
+ var apiPath = url_path_1.default(BASE_PATH, fileID, WATERMARK_SUBRESOURCE);
957
+ return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, null, callback);
958
+ };
959
+ /**
960
+ * Discards a specific file version to the trash. Depending on the enterprise settings
961
+ * for this user, the item will either be actually deleted from Box or moved to the trash.
962
+ *
963
+ * API Endpoint: '/files/:fileID/version/:versionID'
964
+ * Method: DELETE
965
+ *
966
+ * @param {string} fileID - The file ID which old version will be moved to the trash or delete permanently
967
+ * @param {string} versionID - The ID of the version to move to the trash or delete permanently
968
+ * @param {Object} [options] Optional parameters
969
+ * @param {string} [options.etag] Only delete the version of the file etag matches
970
+ * @param {Function} [callback] - Empty response body, error otherwise
971
+ * @returns {Promise<void>} A promise resolving to nothing
972
+ */
973
+ Files.prototype.deleteVersion = function (fileID, versionID, options, callback) {
974
+ // Switch around arguments if necessary for backwwards compatibility
975
+ if (typeof options === 'function') {
976
+ callback = options;
977
+ options = {};
978
+ }
979
+ var params = {};
980
+ if (options && options.etag) {
981
+ params.headers = {
982
+ 'If-Match': options.etag,
983
+ };
984
+ }
985
+ var apiPath = url_path_1.default(BASE_PATH, fileID, VERSIONS_SUBRESOURCE, versionID);
986
+ return this.client.wrapWithDefaultHandler(this.client.del)(apiPath, params, callback);
987
+ };
988
+ /**
989
+ * Creates a session used to upload a new file in chunks.. This will first
990
+ * verify that the file can be created and then open a session for uploading
991
+ * pieces of the file.
992
+ *
993
+ * API Endpoint: '/files/upload_sessions'
994
+ * Method: POST
995
+ *
996
+ * @param {string} folderID - The ID of the folder to upload the file to
997
+ * @param {int} size - The size of the file that will be uploaded
998
+ * @param {string} name - The name of the file to be created
999
+ * @param {Function} [callback] - Passed the upload session info if successful
1000
+ * @returns {Promise<Object>} A promise resolving to the new upload session object
1001
+ */
1002
+ Files.prototype.createUploadSession = function (folderID, size, name, callback) {
1003
+ var apiURL = this.client._uploadBaseURL +
1004
+ url_path_1.default(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE), params = {
1005
+ body: {
1006
+ folder_id: folderID,
1007
+ file_size: size,
1008
+ file_name: name,
1009
+ },
1010
+ };
1011
+ return this.client.wrapWithDefaultHandler(this.client.post)(apiURL, params, callback);
1012
+ };
1013
+ /**
1014
+ * Creates a session used to upload a new version of a file in chunks. This
1015
+ * will first verify that the version can be created and then open a session for
1016
+ * uploading pieces of the file.
1017
+ *
1018
+ * API Endpoint: '/files/:fileID/upload_sessions'
1019
+ * Method: POST
1020
+ *
1021
+ * @param {string} fileID - The ID of the file to upload a new version of
1022
+ * @param {int} size - The size of the file that will be uploaded
1023
+ * @param {Function} [callback] - Passed the upload session info if successful
1024
+ * @returns {Promise<Object>} A promise resolving to the new upload session object
1025
+ */
1026
+ Files.prototype.createNewVersionUploadSession = function (fileID, size, callback) {
1027
+ var apiURL = this.client._uploadBaseURL +
1028
+ url_path_1.default(BASE_PATH, fileID, UPLOAD_SESSION_SUBRESOURCE), params = {
1029
+ body: {
1030
+ file_size: size,
1031
+ },
1032
+ };
1033
+ return this.client.wrapWithDefaultHandler(this.client.post)(apiURL, params, callback);
1034
+ };
1035
+ /**
1036
+ * Uploads a chunk of a file to an open upload session
1037
+ *
1038
+ * API Endpoint: '/files/upload_sessions/:sessionID'
1039
+ * Method: PUT
1040
+ *
1041
+ * @param {string} sessionID - The ID of the upload session to upload to
1042
+ * @param {Buffer|string} part - The chunk of the file to upload
1043
+ * @param {int} offset - The byte position where the chunk begins in the file
1044
+ * @param {int} totalSize - The total size of the file being uploaded
1045
+ * @param {Function} [callback] - Passed the part definition if successful
1046
+ * @returns {Promise<Object>} A promise resolving to the part object
1047
+ */
1048
+ Files.prototype.uploadPart = function (sessionID, part, offset, totalSize, callback) {
1049
+ var apiURL = this.client._uploadBaseURL +
1050
+ url_path_1.default(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID);
1051
+ var hash = crypto_1.default.createHash('sha1').update(part).digest('base64');
1052
+ var params = {
1053
+ headers: {
1054
+ 'Content-Type': 'application/octet-stream',
1055
+ Digest: "SHA=" + hash,
1056
+ 'Content-Range': "bytes " + offset + "-" + (offset + part.length - 1) + "/" + totalSize,
1057
+ },
1058
+ json: false,
1059
+ body: part,
1060
+ };
1061
+ return this.client
1062
+ .put(apiURL, params)
1063
+ .then(function (response /* FIXME */) {
1064
+ if (response.statusCode !== 200) {
1065
+ throw errors_1.default.buildUnexpectedResponseError(response);
1066
+ }
1067
+ return JSON.parse(response.body);
1068
+ })
1069
+ .asCallback(callback);
1070
+ };
1071
+ /**
1072
+ * Commit an upload session after all parts have been uploaded, creating the new file
1073
+ *
1074
+ * API Endpoint: '/files/upload_sessions/:sessionID/commit'
1075
+ * Method: POST
1076
+ *
1077
+ * @param {string} sessionID - The ID of the upload session to commit
1078
+ * @param {string} fileHash - The base64-encoded SHA-1 hash of the file being uploaded
1079
+ * @param {Object} [options] - Optional parameters set on the created file, can be left null
1080
+ * @param {UploadPart[]} [options.parts] The list of uploaded parts to be committed, will be fetched from the API otherwise
1081
+ * @param {Function} [callback] - Passed the new file information if successful
1082
+ * @returns {Promise<Object>} A promise resolving to the uploaded file object
1083
+ */
1084
+ Files.prototype.commitUploadSession = function (sessionID, fileHash, options, callback) {
1085
+ var _this = this;
1086
+ options = options || {};
1087
+ var userParts;
1088
+ if (options.parts) {
1089
+ userParts = options.parts;
1090
+ delete options.parts;
1091
+ }
1092
+ var apiURL = this.client._uploadBaseURL +
1093
+ url_path_1.default(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID, 'commit'), params = {
1094
+ headers: {
1095
+ Digest: "SHA=" + fileHash,
1096
+ },
1097
+ body: {
1098
+ attributes: options,
1099
+ },
1100
+ };
1101
+ var fetchParts = function (offset /* FIXME */, fetchedParts /* FIXME */) {
1102
+ var pagingOptions = {
1103
+ limit: 1000,
1104
+ offset: offset,
1105
+ };
1106
+ return _this.getUploadSessionParts(sessionID, pagingOptions).then(function (data /* FIXME */) {
1107
+ fetchedParts = fetchedParts.concat(data.entries);
1108
+ if (data.offset + data.entries.length >= data.total_count) {
1109
+ return bluebird_1.default.resolve(fetchedParts);
1110
+ }
1111
+ return fetchParts(offset + data.limit, fetchedParts);
1112
+ });
1113
+ };
1114
+ return (userParts ? bluebird_1.default.resolve(userParts) : fetchParts(0, []))
1115
+ .then(function (parts /* FIXME */) {
1116
+ // Commit the upload with the list of parts
1117
+ params.body.parts = parts;
1118
+ return _this.client.post(apiURL, params);
1119
+ })
1120
+ .then(function (response /* FIXME */) {
1121
+ if (response.statusCode === 201) {
1122
+ return response.body;
1123
+ }
1124
+ if (response.statusCode === 202) {
1125
+ var retryInterval = response.headers['retry-after'] || 1;
1126
+ return bluebird_1.default.delay(retryInterval * 1000).then(function () {
1127
+ // Ensure we don't have to fetch parts from the API again on retry
1128
+ options = Object.assign({}, options, { parts: params.body.parts });
1129
+ return _this.commitUploadSession(sessionID, fileHash, options);
1130
+ });
1131
+ }
1132
+ throw errors_1.default.buildUnexpectedResponseError(response);
1133
+ })
1134
+ .asCallback(callback);
1135
+ };
1136
+ /**
1137
+ * Abort an upload session, discarding any chunks that were uploaded to it
1138
+ *
1139
+ * API Endpoint: '/files/upload_sessions/:sessionID'
1140
+ * Method: DELETE
1141
+ *
1142
+ * @param {string} sessionID - The ID of the upload session to commit
1143
+ * @param {Function} [callback] - Passed nothing if successful, error otherwise
1144
+ * @returns {Promise<void>} A promise resolving to nothing
1145
+ */
1146
+ Files.prototype.abortUploadSession = function (sessionID, callback) {
1147
+ var apiURL = this.client._uploadBaseURL +
1148
+ url_path_1.default(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID);
1149
+ return this.client.wrapWithDefaultHandler(this.client.del)(apiURL, null, callback);
1150
+ };
1151
+ /**
1152
+ * Get a list of all parts that have been uploaded to an upload session
1153
+ *
1154
+ * API Endpoint: '/files/upload_sessions/:sessionID/parts'
1155
+ * Method: GET
1156
+ *
1157
+ * @param {string} sessionID - The ID of the session to get a list of parts from
1158
+ * @param {Object} [options] - Optional parameters, can be left null
1159
+ * @param {string} [options.offset] - Paging offset for the list of parts
1160
+ * @param {int} [options.limit] - Maximum number of parts to return
1161
+ * @param {Function} [callback] - Passed the list of parts if successful
1162
+ * @returns {Promise<Object>} A promise resolving to the collection of uploaded parts
1163
+ */
1164
+ Files.prototype.getUploadSessionParts = function (sessionID, options, callback) {
1165
+ var apiURL = this.client._uploadBaseURL +
1166
+ url_path_1.default(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID, 'parts'), params = {
1167
+ qs: options,
1168
+ };
1169
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiURL, params, callback);
1170
+ };
1171
+ /**
1172
+ * Get the status of an upload session, e.g. whether or not is has started or
1173
+ * finished committing
1174
+ *
1175
+ * API Endpoint: '/files/upload_sessions/:sessionID'
1176
+ * Method: GET
1177
+ *
1178
+ * @param {string} sessionID - The ID of the upload session to get the status of
1179
+ * @param {Function} [callback] - Passed the session status if successful
1180
+ * @returns {Promise<Object>} A promise resolving to the upload session object
1181
+ */
1182
+ Files.prototype.getUploadSession = function (sessionID, callback) {
1183
+ var apiURL = this.client._uploadBaseURL +
1184
+ url_path_1.default(BASE_PATH, UPLOAD_SESSION_SUBRESOURCE, sessionID);
1185
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiURL, null, callback);
1186
+ };
1187
+ /**
1188
+ * Upload a file in chunks, which is generally faster and more reliable for
1189
+ * large files.
1190
+ *
1191
+ * API Endpoint: '/files/upload_sessions'
1192
+ * Method: POST
1193
+ *
1194
+ * @param {string} folderID - The ID of the folder to upload the file to
1195
+ * @param {int} size - The size of the file that will be uploaded
1196
+ * @param {string} name - The name of the file to be created
1197
+ * @param {Buffer|string|Readable} file - The file to upload
1198
+ * @param {Object} [options] - Optional parameters for the upload
1199
+ * @param {int} [options.parallelism] The number of chunks to upload concurrently
1200
+ * @param {int} [options.retryInterval] The amount of time to wait before retrying a failed chunk upload, in ms
1201
+ * @param {Object} [options.fileAttributes] Attributes to set on the newly-uploaded file
1202
+ * @param {Function} [callback] - Passed the uploader if successful
1203
+ * @returns {Promise<ChunkedUploader>} A promise resolving to the chunked uploader
1204
+ */
1205
+ Files.prototype.getChunkedUploader = function (folderID, size, name, file, options, callback) {
1206
+ var _this = this;
1207
+ if (file instanceof stream_1.Readable) {
1208
+ // Need to pause the stream immediately to prevent certain libraries,
1209
+ // e.g. request from placing the stream into flowing mode and consuming bytes
1210
+ file.pause();
1211
+ }
1212
+ return this.createUploadSession(folderID, size, name)
1213
+ .then(function (sessionInfo /* FIXME */) {
1214
+ return new ChunkedUploader(_this.client, sessionInfo, file, size, options);
1215
+ })
1216
+ .asCallback(callback);
1217
+ };
1218
+ /**
1219
+ * Upload a new file version in chunks, which is generally faster and more
1220
+ * reliable for large files.
1221
+ *
1222
+ * API Endpoint: '/files/:fileID/upload_sessions'
1223
+ * Method: POST
1224
+ *
1225
+ * @param {string} fileID - The ID of the file to upload a new version of
1226
+ * @param {int} size - The size of the file that will be uploaded
1227
+ * @param {Buffer|string|Readable} file - The file to upload
1228
+ * @param {Object} [options] - Optional parameters for the upload
1229
+ * @param {int} [options.parallelism] The number of chunks to upload concurrently
1230
+ * @param {int} [options.retryInterval] The amount of time to wait before retrying a failed chunk upload, in ms
1231
+ * @param {Object} [options.fileAttributes] Attributes to set on the updated file object
1232
+ * @param {Function} [callback] - Passed the uploader if successful
1233
+ * @returns {Promise<ChunkedUploader>} A promise resolving to the chunked uploader
1234
+ */
1235
+ Files.prototype.getNewVersionChunkedUploader = function (fileID, size, file, options, callback) {
1236
+ var _this = this;
1237
+ if (file instanceof stream_1.Readable) {
1238
+ // Need to pause the stream immediately to prevent certain libraries,
1239
+ // e.g. request from placing the stream into flowing mode and consuming bytes
1240
+ file.pause();
1241
+ }
1242
+ return this.createNewVersionUploadSession(fileID, size)
1243
+ .then(function (sessionInfo /* FIXME */) {
1244
+ return new ChunkedUploader(_this.client, sessionInfo, file, size, options);
1245
+ })
1246
+ .asCallback(callback);
1247
+ };
1248
+ /**
1249
+ * Requests collaborations on a given file.
1250
+ *
1251
+ * API Endpoint: '/files/:fileID/collaborations'
1252
+ * Method: GET
1253
+ *
1254
+ * @param {string} fileID - Box ID of the file being requested
1255
+ * @param {Object} [options] - Additional options. Can be left null in most cases.
1256
+ * @param {int} [options.limit] - The maximum number of collaborations to return
1257
+ * @param {int} [options.offset] - Paging parameter for the collaborations collection
1258
+ * @param {string} [options.fields] - Comma-separated list of fields to return on the collaboration objects
1259
+ * @param {Function} [callback] - Passed the collaborations if successful, error otherwise
1260
+ * @returns {Promise<Object>} A promise resolving to the collection of collaborations on the file
1261
+ */
1262
+ Files.prototype.getCollaborations = function (fileID, options, callback) {
1263
+ var params = {
1264
+ qs: options,
1265
+ };
1266
+ var apiPath = url_path_1.default(BASE_PATH, fileID, '/collaborations');
1267
+ return this.client.wrapWithDefaultHandler(this.client.get)(apiPath, params, callback);
1268
+ };
1269
+ /**
1270
+ * Requests information for all representation objects generated for a specific Box file
1271
+ *
1272
+ * API Endpoint: '/files/:fileID?fields=representations'
1273
+ * Method : GET
1274
+ *
1275
+ * @param {string} fileID - Box ID of the file being requested
1276
+ * @param {client.files.representation} representationType - The x-rep-hints value the application should create a
1277
+ * representation for. This value can either come from FileRepresentationType enum or manually created
1278
+ * @param {Object} [options] - Additional options. Can be left empty
1279
+ * @param {boolean} [options.generateRepresentations = false] - Set to true to return representation info where all states resolve to success.
1280
+ * @param {Function} [callback] - Passed an array of representaton objects if successful
1281
+ * @returns {Promise<Object>} A promise resolving to the representation response objects
1282
+ */
1283
+ Files.prototype.getRepresentationInfo = function (fileID, representationType, options, callback) {
1284
+ var _this = this;
1285
+ if (typeof options === 'function') {
1286
+ callback = options;
1287
+ options = {};
1288
+ }
1289
+ if (!representationType && options && options.generateRepresentations) {
1290
+ throw new Error('Must provide a valid X-Rep-Hints string to get representations with a success status');
1291
+ }
1292
+ var params = {
1293
+ qs: {
1294
+ fields: 'representations',
1295
+ },
1296
+ headers: {
1297
+ 'x-rep-hints': representationType,
1298
+ },
1299
+ };
1300
+ var apiPath = url_path_1.default(BASE_PATH, fileID);
1301
+ return this.client
1302
+ .get(apiPath, params)
1303
+ .then(function (response /* FIXME */) {
1304
+ switch (response.statusCode) {
1305
+ // 202 - A Box file representation will be generated, but is not ready yet
1306
+ case http_status_1.default.ACCEPTED:
1307
+ throw errors_1.default.buildResponseError(response, 'Representation not ready at this time');
1308
+ // 200 - A Boxfile representation generated successfully
1309
+ // return the representation object
1310
+ case http_status_1.default.OK:
1311
+ if (options && options.generateRepresentations) {
1312
+ var data = response.body.representations.entries;
1313
+ var promiseArray = data.map(function (entry /* FIXME */) {
1314
+ switch (entry.status.state) {
1315
+ case 'success':
1316
+ case 'viewable':
1317
+ case 'error':
1318
+ return bluebird_1.default.resolve(entry);
1319
+ default:
1320
+ return pollRepresentationInfo(_this.client, entry.info.url);
1321
+ }
1322
+ });
1323
+ return bluebird_1.default.all(promiseArray).then(function (entries) { return ({ entries: entries }); });
1324
+ }
1325
+ return response.body.representations;
1326
+ // Unexpected Response
1327
+ default:
1328
+ throw errors_1.default.buildUnexpectedResponseError(response);
1329
+ }
1330
+ })
1331
+ .asCallback(callback);
1332
+ };
1333
+ /**
1334
+ * Get the contents of a representation of a file, e.g, the binary content of an image or pdf.
1335
+ *
1336
+ * API Endpoint: '/files/:fileID?fields=representations'
1337
+ * Method : GET
1338
+ *
1339
+ * @param {string} fileID The file ID to get the representation of
1340
+ * @param {string} representationType The X-Rep-Hints type to request
1341
+ * @param {Object} [options] Optional parameters
1342
+ * @param {string} [options.assetPath] Asset path for representations with multiple files
1343
+ * @param {Function} [callback] Passed a stream over the representation contents if successful
1344
+ * @returns {Promise<Readable>} A promise resolving to a stream over the representation contents
1345
+ */
1346
+ Files.prototype.getRepresentationContent = function (fileID, representationType, options, callback) {
1347
+ var _this = this;
1348
+ if (!representationType) {
1349
+ throw new Error('Must provide a valid X-Rep-Hints string');
1350
+ }
1351
+ options = Object.assign({ assetPath: '' }, options);
1352
+ return this.getRepresentationInfo(fileID, representationType)
1353
+ .then(function (reps /* FIXME */) {
1354
+ var repInfo = reps.entries.pop();
1355
+ if (!repInfo) {
1356
+ throw new Error('Could not get information for requested representation');
1357
+ }
1358
+ switch (repInfo.status.state) {
1359
+ case 'success':
1360
+ case 'viewable':
1361
+ return repInfo.content.url_template;
1362
+ case 'error':
1363
+ throw new Error('Representation had error status');
1364
+ case 'none':
1365
+ case 'pending':
1366
+ return pollRepresentationInfo(_this.client, repInfo.info.url).then(function (info /* FIXME */) {
1367
+ if (info.status.state === 'error') {
1368
+ throw new Error('Representation had error status');
1369
+ }
1370
+ return info.content.url_template;
1371
+ });
1372
+ default:
1373
+ throw new Error("Unknown representation status: " + repInfo.status.state);
1374
+ }
1375
+ })
1376
+ .then(function (assetURLTemplate) {
1377
+ var url = url_template_1.default
1378
+ .parse(assetURLTemplate)
1379
+ .expand({ asset_path: options.assetPath });
1380
+ return _this.client.get(url, { streaming: true });
1381
+ })
1382
+ .asCallback(callback);
1383
+ };
1384
+ /**
1385
+ * Creates a zip of multiple files and folders.
1386
+ *
1387
+ * API Endpoint: '/zip_downloads'
1388
+ * Method: POST
1389
+ *
1390
+ * @param {name} name - The name of the zip file to be created
1391
+ * @param {Array} items - Array of files or folders to be part of the created zip
1392
+ * @param {Function} [callback] Passed a zip information object
1393
+ * @returns {Promise<string>} A promise resolving to a zip information object
1394
+ */
1395
+ Files.prototype.createZip = function (name, items /* FIXME */, callback) {
1396
+ var params = {
1397
+ body: {
1398
+ download_file_name: name,
1399
+ items: items,
1400
+ },
1401
+ };
1402
+ return this.client.wrapWithDefaultHandler(this.client.post)(ZIP_DOWNLOAD_PATH, params, callback);
1403
+ };
1404
+ /**
1405
+ * Creates a zip of multiple files and folders and downloads it.
1406
+ *
1407
+ * API Endpoint: '/zip_downloads'
1408
+ * Method: GET
1409
+ *
1410
+ * @param {name} name - The name of the zip file to be created
1411
+ * @param {Array} items - Array of files or folders to be part of the created zip
1412
+ * @param {Stream} stream - Stream to pipe the readable stream of the zip file
1413
+ * @param {Function} [callback] - Passed a zip download status object
1414
+ * @returns {Promise<Readable>} A promise resolving to a zip download status object
1415
+ */
1416
+ Files.prototype.downloadZip = function (name, items /* FIXME */, stream, callback) {
1417
+ var _this = this;
1418
+ var downloadStreamOptions = {
1419
+ streaming: true,
1420
+ headers: {},
1421
+ };
1422
+ var params = {
1423
+ body: {
1424
+ download_file_name: name,
1425
+ items: items,
1426
+ },
1427
+ };
1428
+ return this.client
1429
+ .post(ZIP_DOWNLOAD_PATH, params)
1430
+ .then(function (response /* FIXME */) {
1431
+ return _this.client
1432
+ .get(response.body.download_url, downloadStreamOptions)
1433
+ .then(function (responseStream) {
1434
+ responseStream.pipe(stream);
1435
+ // eslint-disable-next-line promise/avoid-new
1436
+ return new bluebird_1.default(function (resolve, reject) {
1437
+ responseStream.on('end', function () { return resolve('Done downloading'); });
1438
+ responseStream.on('error', function (error) { return reject(error); });
1439
+ }).then(function () {
1440
+ return _this.client
1441
+ .get(response.body.status_url)
1442
+ .then(function (responseStatus /* FIXME */) { return responseStatus.body; });
1443
+ });
1444
+ });
1445
+ })
1446
+ .asCallback(callback);
1447
+ };
1448
+ return Files;
1449
+ }());
1452
1450
  /**
1453
1451
  * Enum of valid x-rep- hint values for generating representation info
1454
1452
  *
1455
1453
  * @readonly
1456
1454
  * @enum {FileRepresentationType}
1457
1455
  */
1458
- Files.prototype.representation = {
1459
- PDF: '[pdf]',
1460
- THUMBNAIL: '[jpg?dimensions=320x320]',
1461
- IMAGE_MEDIUM: '[jpg?dimensions=1024x1024][png?dimensions=1024x1024]',
1462
- IMAGE_LARGE: '[jpg?dimensions=2048x2048][png?dimensions=2048x2048]',
1463
- EXTRACTED_TEXT: '[extracted_text]'
1464
- };
1465
-
1466
- /**
1467
- * Requests information for all representation objects generated for a specific Box file
1468
- *
1469
- * API Endpoint: '/files/:fileID?fields=representations'
1470
- * Method : GET
1471
- *
1472
- * @param {string} fileID - Box ID of the file being requested
1473
- * @param {client.files.representation} representationType - The x-rep-hints value the application should create a
1474
- * representation for. This value can either come from FileRepresentationType enum or manually created
1475
- * @param {Object} [options] - Additional options. Can be left empty
1476
- * @param {boolean} [options.generateRepresentations = false] - Set to true to return representation info where all states resolve to success.
1477
- * @param {Function} [callback] - Passed an array of representaton objects if successful
1478
- * @returns {Promise<Object>} A promise resolving to the representation response objects
1479
- */
1480
- Files.prototype.getRepresentationInfo = function(fileID, representationType, options, callback) {
1481
- if (typeof options === 'function') {
1482
- callback = options;
1483
- options = {};
1484
- }
1485
- if (!representationType && options && options.generateRepresentations) {
1486
- throw new Error('Must provide a valid X-Rep-Hints string to get representations with a success status');
1487
- }
1488
- var params = {
1489
- qs: {
1490
- fields: 'representations'
1491
- },
1492
- headers: {
1493
- 'x-rep-hints': representationType
1494
- }
1495
- };
1496
- var apiPath = urlPath(BASE_PATH, fileID);
1497
-
1498
- return this.client.get(apiPath, params)
1499
- .then(response => {
1500
- switch (response.statusCode) {
1501
- // 202 - A Box file representation will be generated, but is not ready yet
1502
- case httpStatusCodes.ACCEPTED:
1503
- throw errors.buildResponseError(response, 'Representation not ready at this time');
1504
-
1505
- // 200 - A Boxfile representation generated successfully
1506
- // return the representation object
1507
- case httpStatusCodes.OK:
1508
-
1509
- if (options && options.generateRepresentations) {
1510
-
1511
- var data = response.body.representations.entries;
1512
- var promiseArray = data.map(entry => {
1513
- switch (entry.status.state) {
1514
- case 'success':
1515
- case 'viewable':
1516
- case 'error':
1517
- return Promise.resolve(entry);
1518
- default:
1519
- return pollRepresentationInfo(this.client, entry.info.url);
1520
- }
1521
- });
1522
-
1523
- return Promise.all(promiseArray).then(entries => ({entries}) );
1524
-
1525
- }
1526
-
1527
- return response.body.representations;
1528
-
1529
- // Unexpected Response
1530
- default:
1531
- throw errors.buildUnexpectedResponseError(response);
1532
- }
1533
- })
1534
- .asCallback(callback);
1535
-
1536
-
1537
- };
1538
-
1539
- /**
1540
- * Get the contents of a representation of a file, e.g, the binary content of an image or pdf.
1541
- *
1542
- * API Endpoint: '/files/:fileID?fields=representations'
1543
- * Method : GET
1544
- *
1545
- * @param {string} fileID The file ID to get the representation of
1546
- * @param {string} representationType The X-Rep-Hints type to request
1547
- * @param {Object} [options] Optional parameters
1548
- * @param {string} [options.assetPath] Asset path for representations with multiple files
1549
- * @param {Function} [callback] Passed a stream over the representation contents if successful
1550
- * @returns {Promise<Readable>} A promise resolving to a stream over the representation contents
1551
- */
1552
- Files.prototype.getRepresentationContent = function(fileID, representationType, options, callback) {
1553
-
1554
- if (!representationType) {
1555
- throw new Error('Must provide a valid X-Rep-Hints string');
1556
- }
1557
-
1558
- options = Object.assign({ assetPath: '' }, options);
1559
-
1560
- return this.getRepresentationInfo(fileID, representationType)
1561
- .then(reps => {
1562
-
1563
- var repInfo = reps.entries.pop();
1564
- if (!repInfo) {
1565
- throw new Error('Could not get information for requested representation');
1566
- }
1567
-
1568
- switch (repInfo.status.state) {
1569
-
1570
- case 'success':
1571
- case 'viewable':
1572
- return repInfo.content.url_template;
1573
- case 'error':
1574
- throw new Error('Representation had error status');
1575
- case 'none':
1576
- case 'pending':
1577
- return pollRepresentationInfo(this.client, repInfo.info.url)
1578
- .then(info => {
1579
- if (info.status.state === 'error') {
1580
- throw new Error('Representation had error status');
1581
- }
1582
- return info.content.url_template;
1583
- });
1584
- default:
1585
- throw new Error(`Unknown representation status: ${repInfo.status.state}`);
1586
- }
1587
- })
1588
- .then(assetURLTemplate => {
1589
- var url = urlTemplate.parse(assetURLTemplate).expand({ asset_path: options.assetPath });
1590
- return this.client.get(url, { streaming: true });
1591
- })
1592
- .asCallback(callback);
1593
- };
1594
-
1595
- /**
1596
- * Creates a zip of multiple files and folders.
1597
- *
1598
- * API Endpoint: '/zip_downloads'
1599
- * Method: POST
1600
- *
1601
- * @param {name} name - The name of the zip file to be created
1602
- * @param {Array} items - Array of files or folders to be part of the created zip
1603
- * @param {Function} [callback] Passed a zip information object
1604
- * @returns {Promise<string>} A promise resolving to a zip information object
1605
- */
1606
- Files.prototype.createZip = function(name, items, callback) {
1607
- var params = {
1608
- body: {
1609
- download_file_name: name,
1610
- items
1611
- }
1612
- };
1613
-
1614
- return this.client.wrapWithDefaultHandler(this.client.post)(ZIP_DOWNLOAD_PATH, params, callback);
1615
- };
1616
-
1617
- /**
1618
- * Creates a zip of multiple files and folders and downloads it.
1619
- *
1620
- * API Endpoint: '/zip_downloads'
1621
- * Method: GET
1622
- *
1623
- * @param {name} name - The name of the zip file to be created
1624
- * @param {Array} items - Array of files or folders to be part of the created zip
1625
- * @param {Stream} stream - Stream to pipe the readable stream of the zip file
1626
- * @param {Function} [callback] - Passed a zip download status object
1627
- * @returns {Promise<Readable>} A promise resolving to a zip download status object
1628
- */
1629
- Files.prototype.downloadZip = function(name, items, stream, callback) {
1630
- var downloadStreamOptions = {
1631
- streaming: true,
1632
- headers: {}
1633
- };
1634
-
1635
- var params = {
1636
- body: {
1637
- download_file_name: name,
1638
- items
1639
- }
1640
- };
1641
-
1642
- return this.client.post(ZIP_DOWNLOAD_PATH, params)
1643
- .then(response => this.client.get(response.body.download_url, downloadStreamOptions)
1644
- .then(responseStream => {
1645
- responseStream.pipe(stream);
1646
- // eslint-disable-next-line promise/avoid-new
1647
- return new Promise((resolve, reject) => {
1648
- responseStream.on('end', () => resolve('Done downloading'));
1649
- responseStream.on('error', error => reject(error));
1650
- }).then(() => this.client.get(response.body.status_url).then(responseStatus => responseStatus.body));
1651
- })
1652
- )
1653
- .asCallback(callback);
1654
- };
1655
-
1656
- /**
1657
- * @module box-node-sdk/lib/managers/files
1658
- * @see {@Link Files}
1659
- */
1456
+ Files.prototype.representation = FileRepresentationType;
1660
1457
  module.exports = Files;
1458
+ //# sourceMappingURL=files.js.map