box-node-sdk 1.36.0 → 1.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -3
- package/README.md +3 -1
- package/lib/api-request-manager.d.ts +38 -0
- package/lib/api-request-manager.js +48 -55
- package/lib/api-request-manager.js.map +1 -0
- package/lib/api-request.d.ts +137 -0
- package/lib/api-request.js +202 -281
- package/lib/api-request.js.map +1 -0
- package/lib/box-client.d.ts +269 -0
- package/lib/box-client.js +551 -713
- package/lib/box-client.js.map +1 -0
- package/lib/box-node-sdk.d.ts +216 -0
- package/lib/box-node-sdk.js +317 -352
- package/lib/box-node-sdk.js.map +1 -0
- package/lib/chunked-uploader.d.ts +129 -0
- package/lib/chunked-uploader.js +287 -358
- package/lib/chunked-uploader.js.map +1 -0
- package/lib/enterprise-event-stream.d.ts +82 -0
- package/lib/enterprise-event-stream.js +189 -203
- package/lib/enterprise-event-stream.js.map +1 -0
- package/lib/event-stream.d.ts +92 -0
- package/lib/event-stream.js +274 -302
- package/lib/event-stream.js.map +1 -0
- package/lib/managers/collaboration-allowlist.d.ts +137 -0
- package/lib/managers/collaboration-allowlist.js +200 -0
- package/lib/managers/collaboration-allowlist.js.map +1 -0
- package/lib/managers/collaboration-whitelist.d.ts +3 -0
- package/lib/managers/collaboration-whitelist.js +8 -222
- package/lib/managers/collaboration-whitelist.js.map +1 -0
- package/lib/managers/collaborations.d.ts +166 -0
- package/lib/managers/collaborations.js +225 -258
- package/lib/managers/collaborations.js.map +1 -0
- package/lib/managers/collections.d.ts +42 -0
- package/lib/managers/collections.js +45 -50
- package/lib/managers/collections.js.map +1 -0
- package/lib/managers/comments.d.ts +103 -0
- package/lib/managers/comments.js +158 -173
- package/lib/managers/comments.js.map +1 -0
- package/lib/managers/device-pins.d.ts +52 -0
- package/lib/managers/device-pins.js +75 -88
- package/lib/managers/device-pins.js.map +1 -0
- package/lib/managers/enterprise.d.ts +162 -0
- package/lib/managers/enterprise.js +168 -199
- package/lib/managers/enterprise.js.map +1 -0
- package/lib/managers/events.d.ts +179 -0
- package/lib/managers/events.js +232 -254
- package/lib/managers/events.js.map +1 -0
- package/lib/managers/files.d.ts +773 -0
- package/lib/managers/files.js +1401 -1602
- package/lib/managers/files.js.map +1 -0
- package/lib/managers/folders.d.ts +347 -0
- package/lib/managers/folders.js +551 -630
- package/lib/managers/folders.js.map +1 -0
- package/lib/managers/groups.d.ts +202 -0
- package/lib/managers/groups.js +238 -288
- package/lib/managers/groups.js.map +1 -0
- package/lib/managers/legal-hold-policies.d.ts +190 -0
- package/lib/managers/legal-hold-policies.js +228 -272
- package/lib/managers/legal-hold-policies.js.map +1 -0
- package/lib/managers/metadata.d.ts +228 -0
- package/lib/managers/metadata.js +265 -328
- package/lib/managers/metadata.js.map +1 -0
- package/lib/managers/recent-items.d.ts +38 -0
- package/lib/managers/recent-items.js +32 -39
- package/lib/managers/recent-items.js.map +1 -0
- package/lib/managers/retention-policies.d.ts +251 -0
- package/lib/managers/retention-policies.js +278 -281
- package/lib/managers/retention-policies.js.map +1 -0
- package/lib/managers/search.d.ts +82 -0
- package/lib/managers/search.js +68 -88
- package/lib/managers/search.js.map +1 -0
- package/lib/managers/shared-items.d.ts +33 -0
- package/lib/managers/shared-items.js +54 -62
- package/lib/managers/shared-items.js.map +1 -0
- package/lib/managers/storage-policies.d.ts +86 -0
- package/lib/managers/storage-policies.js +108 -142
- package/lib/managers/storage-policies.js.map +1 -0
- package/lib/managers/tasks.d.ts +161 -0
- package/lib/managers/tasks.js +219 -260
- package/lib/managers/tasks.js.map +1 -0
- package/lib/managers/terms-of-service.d.ts +161 -0
- package/lib/managers/terms-of-service.js +250 -273
- package/lib/managers/terms-of-service.js.map +1 -0
- package/lib/managers/trash.d.ts +30 -0
- package/lib/managers/trash.js +30 -41
- package/lib/managers/trash.js.map +1 -0
- package/lib/managers/users.d.ts +130 -0
- package/lib/managers/users.js +160 -203
- package/lib/managers/users.js.map +1 -0
- package/lib/managers/web-links.d.ts +127 -0
- package/lib/managers/web-links.js +183 -209
- package/lib/managers/web-links.js.map +1 -0
- package/lib/managers/webhooks.d.ts +166 -0
- package/lib/managers/webhooks.js +312 -305
- package/lib/managers/webhooks.js.map +1 -0
- package/lib/sessions/anonymous-session.d.ts +69 -0
- package/lib/sessions/anonymous-session.js +88 -102
- package/lib/sessions/anonymous-session.js.map +1 -0
- package/lib/sessions/app-auth-session.d.ts +92 -0
- package/lib/sessions/app-auth-session.js +140 -160
- package/lib/sessions/app-auth-session.js.map +1 -0
- package/lib/sessions/basic-session.d.ts +56 -0
- package/lib/sessions/basic-session.js +40 -50
- package/lib/sessions/basic-session.js.map +1 -0
- package/lib/sessions/persistent-session.d.ts +96 -0
- package/lib/sessions/persistent-session.js +191 -211
- package/lib/sessions/persistent-session.js.map +1 -0
- package/lib/token-manager.d.ts +191 -0
- package/lib/token-manager.js +390 -465
- package/lib/token-manager.js.map +1 -0
- package/lib/util/config.d.ts +86 -0
- package/lib/util/config.js +146 -152
- package/lib/util/config.js.map +1 -0
- package/lib/util/errors.d.ts +50 -0
- package/lib/util/errors.js +134 -145
- package/lib/util/errors.js.map +1 -0
- package/lib/util/exponential-backoff.d.ts +11 -0
- package/lib/util/exponential-backoff.js +10 -22
- package/lib/util/exponential-backoff.js.map +1 -0
- package/lib/util/paging-iterator.d.ts +53 -0
- package/lib/util/paging-iterator.js +202 -218
- package/lib/util/paging-iterator.js.map +1 -0
- package/lib/util/url-path.d.ts +16 -0
- package/lib/util/url-path.js +20 -35
- package/lib/util/url-path.js.map +1 -0
- package/package.json +14 -3
package/lib/chunked-uploader.js
CHANGED
|
@@ -1,378 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* @fileoverview Upload manager for large file uploads
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
* @param {Error} err The error that occurred
|
|
24
|
-
* @private
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Event for when the upload is successfully aborted
|
|
29
|
-
* @event ChunkedUploader#aborted
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Event for when the abort fails because the upload session is not destroyed.
|
|
34
|
-
* In general, the abort can be retried, and no new chunks will be uploaded.
|
|
35
|
-
* @event ChunkedUploader#abortFailed
|
|
36
|
-
* @param {Error} err The error that occurred
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Event for when a chunk fails to upload. Note that the chunk will automatically
|
|
41
|
-
* retry until it is successfully uploaded.
|
|
42
|
-
* @event ChunkedUploader#chunkError
|
|
43
|
-
* @param {Error} err The error that occurred during chunk upload
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Event for when a chunk is successfully uploaded
|
|
48
|
-
* @event ChunkedUploader#chunkUploaded
|
|
49
|
-
* @param {UploadPart} data The data for the uploaded chunk
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Event for when the entire upload is complete
|
|
54
|
-
* @event ChunkedUploader#uploadComplete
|
|
55
|
-
* @param {Object} file The file object for the newly-uploaded file
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Event for when an upload fails
|
|
60
|
-
* @event ChunkedUploader#error
|
|
61
|
-
* @param {Error} err The error that occurred
|
|
62
|
-
*/
|
|
63
|
-
|
|
5
|
+
var __extends = (this && this.__extends) || (function () {
|
|
6
|
+
var extendStatics = function (d, b) {
|
|
7
|
+
extendStatics = Object.setPrototypeOf ||
|
|
8
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
9
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
10
|
+
return extendStatics(d, b);
|
|
11
|
+
};
|
|
12
|
+
return function (d, b) {
|
|
13
|
+
if (typeof b !== "function" && b !== null)
|
|
14
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
15
|
+
extendStatics(d, b);
|
|
16
|
+
function __() { this.constructor = d; }
|
|
17
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
18
|
+
};
|
|
19
|
+
})();
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
var bluebird_1 = require("bluebird");
|
|
64
24
|
// -----------------------------------------------------------------------------
|
|
65
25
|
// Requirements
|
|
66
26
|
// -----------------------------------------------------------------------------
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
crypto = require('crypto');
|
|
71
|
-
|
|
27
|
+
var events_1 = require("events");
|
|
28
|
+
var stream_1 = require("stream");
|
|
29
|
+
var crypto_1 = __importDefault(require("crypto"));
|
|
72
30
|
// -----------------------------------------------------------------------------
|
|
73
31
|
// Private
|
|
74
32
|
// -----------------------------------------------------------------------------
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
retryInterval: 1000
|
|
33
|
+
var DEFAULT_OPTIONS = Object.freeze({
|
|
34
|
+
parallelism: 4,
|
|
35
|
+
retryInterval: 1000,
|
|
79
36
|
});
|
|
80
|
-
|
|
81
37
|
/**
|
|
82
38
|
* Chunk of a file to be uploaded, which handles trying to upload itself until
|
|
83
39
|
* it succeeds.
|
|
84
40
|
* @private
|
|
85
41
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
cancel() {
|
|
163
|
-
|
|
164
|
-
clearTimeout(this.retry);
|
|
165
|
-
this.chunk = null;
|
|
166
|
-
this.canceled = true;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
42
|
+
var Chunk = /** @class */ (function (_super) {
|
|
43
|
+
__extends(Chunk, _super);
|
|
44
|
+
/**
|
|
45
|
+
* Create a Chunk, representing a part of a file being uploaded
|
|
46
|
+
* @param {BoxClient} client The Box SDK client
|
|
47
|
+
* @param {string} sessionID The ID of the upload session the chunk belongs to
|
|
48
|
+
* @param {Buffer|string} chunk The chunk that was uploaded
|
|
49
|
+
* @param {int} offset The byte offset within the file where this chunk begins
|
|
50
|
+
* @param {int} totalSize The total size of the file this chunk belongs to
|
|
51
|
+
* @param {Object} options The options from the ChunkedUploader
|
|
52
|
+
* @param {int} options.retryInterval The number of ms to wait before retrying a chunk upload
|
|
53
|
+
*/
|
|
54
|
+
function Chunk(client, sessionID, chunk, offset, totalSize, options) {
|
|
55
|
+
var _this = _super.call(this) || this;
|
|
56
|
+
_this.client = client;
|
|
57
|
+
_this.sessionID = sessionID;
|
|
58
|
+
_this.chunk = chunk;
|
|
59
|
+
_this.length = chunk.length;
|
|
60
|
+
_this.offset = offset;
|
|
61
|
+
_this.totalSize = totalSize;
|
|
62
|
+
_this.options = options;
|
|
63
|
+
_this.data = null;
|
|
64
|
+
_this.retry = null;
|
|
65
|
+
_this.canceled = false;
|
|
66
|
+
return _this;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the final object representation of this chunk for the API
|
|
70
|
+
* @returns {UploadPart} The chunk object
|
|
71
|
+
*/
|
|
72
|
+
Chunk.prototype.getData = function () {
|
|
73
|
+
return this.data.part;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Upload a chunk to the API
|
|
77
|
+
* @returns {void}
|
|
78
|
+
* @emits Chunk#uploaded
|
|
79
|
+
* @emits Chunk#error
|
|
80
|
+
*/
|
|
81
|
+
Chunk.prototype.upload = function () {
|
|
82
|
+
var _this = this;
|
|
83
|
+
this.client.files.uploadPart(this.sessionID, this.chunk, this.offset, this.totalSize, function (err /* FIXME */, data /* FIXME */) {
|
|
84
|
+
if (_this.canceled) {
|
|
85
|
+
_this.chunk = null;
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (err) {
|
|
89
|
+
// handle the error or retry
|
|
90
|
+
if (err.statusCode) {
|
|
91
|
+
// an API error, probably not retryable!
|
|
92
|
+
_this.emit('error', err);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// maybe a network error, retry
|
|
96
|
+
_this.retry = setTimeout(function () { return _this.upload(); }, _this.options.retryInterval);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Record the chunk data for commit, and try to free up the chunk buffer
|
|
101
|
+
_this.data = data;
|
|
102
|
+
_this.chunk = null;
|
|
103
|
+
_this.emit('uploaded', data);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Cancel trying to upload a chunk, preventing it from retrying and clearing
|
|
108
|
+
* the associated buffer
|
|
109
|
+
* @returns {void}
|
|
110
|
+
*/
|
|
111
|
+
Chunk.prototype.cancel = function () {
|
|
112
|
+
clearTimeout(this.retry); // number or NodeJS.Timeout
|
|
113
|
+
this.chunk = null;
|
|
114
|
+
this.canceled = true;
|
|
115
|
+
};
|
|
116
|
+
return Chunk;
|
|
117
|
+
}(events_1.EventEmitter));
|
|
170
118
|
// -----------------------------------------------------------------------------
|
|
171
119
|
// Public
|
|
172
120
|
// -----------------------------------------------------------------------------
|
|
173
|
-
|
|
174
121
|
/** Manager for uploading a file in chunks */
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
// It's not clear what the SDK can do here, so we just return the error and session info
|
|
361
|
-
// so users can retry if they wish
|
|
362
|
-
if (err) {
|
|
363
|
-
this.emit('error', {
|
|
364
|
-
uploadSession: this._uploadSessionInfo,
|
|
365
|
-
error: err
|
|
366
|
-
});
|
|
367
|
-
this._reject(err);
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
this.emit('uploadComplete', file);
|
|
372
|
-
this._resolve(file);
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
}
|
|
377
|
-
|
|
122
|
+
var ChunkedUploader = /** @class */ (function (_super) {
|
|
123
|
+
__extends(ChunkedUploader, _super);
|
|
124
|
+
/**
|
|
125
|
+
* Create an upload manager
|
|
126
|
+
* @param {BoxClient} client The client to use to upload the file
|
|
127
|
+
* @param {Object} uploadSessionInfo The upload session info to use for chunked upload
|
|
128
|
+
* @param {ReadableStream|Buffer|string} file The file to upload
|
|
129
|
+
* @param {int} size The size of the file to be uploaded
|
|
130
|
+
* @param {Object} [options] Optional parameters
|
|
131
|
+
* @param {int} [options.retryInterval=1000] The number of ms to wait before retrying operations
|
|
132
|
+
* @param {int} [options.parallelism=4] The number of concurrent chunks to upload
|
|
133
|
+
* @param {Object} [options.fileAttributes] Attributes to set on the file during commit
|
|
134
|
+
*/
|
|
135
|
+
function ChunkedUploader(client, uploadSessionInfo, file, size, options) {
|
|
136
|
+
var _this = _super.call(this) || this;
|
|
137
|
+
_this._client = client;
|
|
138
|
+
_this._sessionID = uploadSessionInfo.id;
|
|
139
|
+
_this._partSize = uploadSessionInfo.part_size;
|
|
140
|
+
_this._uploadSessionInfo = uploadSessionInfo;
|
|
141
|
+
if (file instanceof stream_1.Readable) {
|
|
142
|
+
// Pause the stream so we can read specific chunks from it
|
|
143
|
+
_this._stream = file.pause();
|
|
144
|
+
_this._streamBuffer = [];
|
|
145
|
+
}
|
|
146
|
+
else if (file instanceof Buffer || typeof file === 'string') {
|
|
147
|
+
_this._file = file;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
throw new TypeError('file must be a Stream, Buffer, or string!');
|
|
151
|
+
}
|
|
152
|
+
_this._size = size;
|
|
153
|
+
_this._options = Object.assign({}, DEFAULT_OPTIONS, options);
|
|
154
|
+
_this._isStarted = false;
|
|
155
|
+
_this._numChunksInFlight = 0;
|
|
156
|
+
_this._chunks = [];
|
|
157
|
+
_this._position = 0;
|
|
158
|
+
_this._fileHash = crypto_1.default.createHash('sha1');
|
|
159
|
+
return _this;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Start an upload
|
|
163
|
+
* @returns {Promise<Object>} A promise resolving to the uploaded file
|
|
164
|
+
*/
|
|
165
|
+
ChunkedUploader.prototype.start = function () {
|
|
166
|
+
var _this = this;
|
|
167
|
+
if (this._isStarted) {
|
|
168
|
+
return this._promise;
|
|
169
|
+
}
|
|
170
|
+
// Create the initial chunks
|
|
171
|
+
for (var i = 0; i < this._options.parallelism; i++) {
|
|
172
|
+
this._getNextChunk(function (chunk /* FIXME */) {
|
|
173
|
+
return chunk ? _this._uploadChunk(chunk) : _this._commit();
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
this._isStarted = true;
|
|
177
|
+
/* eslint-disable promise/avoid-new */
|
|
178
|
+
this._promise = new bluebird_1.Promise(function (resolve, reject) {
|
|
179
|
+
_this._resolve = resolve;
|
|
180
|
+
_this._reject = reject;
|
|
181
|
+
});
|
|
182
|
+
/* eslint-enable promise/avoid-new */
|
|
183
|
+
return this._promise;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Abort a running upload, which cancels all currently uploading chunks,
|
|
187
|
+
* attempts to free up held memory, and aborts the upload session. This
|
|
188
|
+
* cannot be undone or resumed.
|
|
189
|
+
* @returns {Promise} A promise resolving when the upload is aborted
|
|
190
|
+
* @emits ChunkedUploader#aborted
|
|
191
|
+
* @emits ChunkedUploader#abortFailed
|
|
192
|
+
*/
|
|
193
|
+
ChunkedUploader.prototype.abort = function () {
|
|
194
|
+
var _this = this;
|
|
195
|
+
this._chunks.forEach(function (chunk) { return chunk.removeAllListeners().cancel(); });
|
|
196
|
+
this._chunks = [];
|
|
197
|
+
this._file = null;
|
|
198
|
+
this._stream = null;
|
|
199
|
+
return (this._client.files
|
|
200
|
+
.abortUploadSession(this._sessionID)
|
|
201
|
+
/* eslint-disable promise/always-return */
|
|
202
|
+
.then(function () {
|
|
203
|
+
_this.emit('aborted');
|
|
204
|
+
})
|
|
205
|
+
/* eslint-enable promise/always-return */
|
|
206
|
+
.catch(function (err /* FIXME */) {
|
|
207
|
+
_this.emit('abortFailed', err);
|
|
208
|
+
throw err;
|
|
209
|
+
}));
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* Get the next chunk of the file to be uploaded
|
|
213
|
+
* @param {Function} callback Called with the next chunk of the file to be uploaded
|
|
214
|
+
* @returns {void}
|
|
215
|
+
* @private
|
|
216
|
+
*/
|
|
217
|
+
ChunkedUploader.prototype._getNextChunk = function (callback) {
|
|
218
|
+
var _this = this;
|
|
219
|
+
if (this._position >= this._size) {
|
|
220
|
+
callback(null);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
var buf;
|
|
224
|
+
if (this._file) {
|
|
225
|
+
// Buffer/string case, just get the slice we need
|
|
226
|
+
buf = this._file.slice(this._position, this._position + this._partSize);
|
|
227
|
+
}
|
|
228
|
+
else if (this._streamBuffer.length > 0) {
|
|
229
|
+
buf = this._streamBuffer.shift();
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
// Stream case, need to read
|
|
233
|
+
buf = this._stream.read(this._partSize);
|
|
234
|
+
if (!buf) {
|
|
235
|
+
// stream needs to read more, retry later
|
|
236
|
+
setImmediate(function () { return _this._getNextChunk(callback); });
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
else if (buf.length > this._partSize) {
|
|
240
|
+
// stream is done reading and had extra data, buffer the remainder of the file
|
|
241
|
+
for (var i = 0; i < buf.length; i += this._partSize) {
|
|
242
|
+
this._streamBuffer.push(buf.slice(i, i + this._partSize));
|
|
243
|
+
}
|
|
244
|
+
buf = this._streamBuffer.shift();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
this._fileHash.update(buf);
|
|
248
|
+
var chunk = new Chunk(this._client, this._sessionID, buf, this._position, this._size, this._options);
|
|
249
|
+
this._position += buf.length;
|
|
250
|
+
callback(chunk);
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Upload a chunk
|
|
254
|
+
* @param {Chunk} chunk The chunk to upload
|
|
255
|
+
* @returns {void}
|
|
256
|
+
* @emits ChunkedUploader#chunkError
|
|
257
|
+
* @emits ChunkedUploader#chunkUploaded
|
|
258
|
+
*/
|
|
259
|
+
ChunkedUploader.prototype._uploadChunk = function (chunk /* FIXME */) {
|
|
260
|
+
var _this = this;
|
|
261
|
+
this._numChunksInFlight += 1;
|
|
262
|
+
chunk.on('error', function (err /* FIXME */) { return _this.emit('chunkError', err); });
|
|
263
|
+
chunk.on('uploaded', function (data /* FIXME */) {
|
|
264
|
+
_this._numChunksInFlight -= 1;
|
|
265
|
+
_this.emit('chunkUploaded', data);
|
|
266
|
+
_this._getNextChunk(function (nextChunk /* FIXME */) {
|
|
267
|
+
return nextChunk ? _this._uploadChunk(nextChunk) : _this._commit();
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
chunk.upload();
|
|
271
|
+
this._chunks.push(chunk);
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Commit the upload, finalizing it
|
|
275
|
+
* @returns {void}
|
|
276
|
+
* @emits ChunkedUploader#uploadComplete
|
|
277
|
+
* @emits ChunkedUploader#error
|
|
278
|
+
*/
|
|
279
|
+
ChunkedUploader.prototype._commit = function () {
|
|
280
|
+
var _this = this;
|
|
281
|
+
if (!this._isStarted || this._numChunksInFlight > 0) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
var hash = this._fileHash.digest('base64');
|
|
285
|
+
this._isStarted = false;
|
|
286
|
+
var options = Object.assign({
|
|
287
|
+
parts: this._chunks.map(function (c) { return c.getData(); }),
|
|
288
|
+
}, this._options.fileAttributes);
|
|
289
|
+
this._client.files.commitUploadSession(this._sessionID, hash, options, function (err /* FIMXE */, file /* FIMXE */) {
|
|
290
|
+
// It's not clear what the SDK can do here, so we just return the error and session info
|
|
291
|
+
// so users can retry if they wish
|
|
292
|
+
if (err) {
|
|
293
|
+
_this.emit('error', {
|
|
294
|
+
uploadSession: _this._uploadSessionInfo,
|
|
295
|
+
error: err,
|
|
296
|
+
});
|
|
297
|
+
_this._reject(err);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
_this.emit('uploadComplete', file);
|
|
301
|
+
_this._resolve(file);
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
return ChunkedUploader;
|
|
305
|
+
}(events_1.EventEmitter));
|
|
378
306
|
module.exports = ChunkedUploader;
|
|
307
|
+
//# sourceMappingURL=chunked-uploader.js.map
|