Skip to content

Commit 287c2d4

Browse files
committed
Merge branch 'develop'
2 parents d7de9d0 + a304076 commit 287c2d4

File tree

12 files changed

+1258
-564
lines changed

12 files changed

+1258
-564
lines changed

package-lock.json

Lines changed: 1180 additions & 359 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
/**
1919
* @private
2020
*/
21-
const PICKER_VERSION = '1.17.0';
21+
const PICKER_VERSION = '1.18.0';
2222

2323
/**
2424
* @private

src/lib/api/prefetch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Session, Security, Client } from './../client';
2121
import { PickerOptions } from './../picker';
2222
import { FsRequest } from '../request';
2323
import { cleanUpCallbacks } from './../utils';
24+
import cloneDeep from 'lodash.clonedeep';
2425

2526
// const debug = Debug('fs:prefetch');
2627

@@ -108,7 +109,7 @@ export class Prefetch {
108109

109110
let pickerOptionsToSend;
110111
if (pickerOptions && Object.keys(pickerOptions).length) {
111-
pickerOptionsToSend = cleanUpCallbacks({ ...pickerOptions });
112+
pickerOptionsToSend = cleanUpCallbacks(cloneDeep({ ...pickerOptions }));
112113
}
113114

114115
paramsToSend = {

src/lib/api/upload/uploaders/s3.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ export class S3Uploader extends UploaderAbstract {
9191
* @memberof S3Uploader
9292
*/
9393
public abort(msg?: string): void {
94-
this.cancelToken.cancel(msg || 'Aborted by user');
94+
this.partsQueue.pause();
9595
this.partsQueue.clear();
96+
97+
this.cancelToken.cancel(msg || 'Aborted by user');
9698
}
9799

98100
/**

src/lib/request/adapters/http.ts

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,26 @@ export class HttpAdapter implements AdapterInterface {
179179
data: {},
180180
};
181181

182+
let cancelListener;
183+
184+
if (config.cancelToken) {
185+
cancelListener = config.cancelToken.once('cancel', (reason) => {
186+
// do nothing if promise is resolved by system
187+
if (reason && reason.message === CANCEL_CLEAR) {
188+
return;
189+
}
190+
191+
/* istanbul ignore next: if request is done cancel token should not throw any error */
192+
if (req) {
193+
req.abort();
194+
req = null;
195+
}
196+
197+
debug('Request canceled by user %s, config: %O', reason, config);
198+
return reject(new FsRequestError(`Request aborted. Reason: ${reason}`, config, null, FsRequestErrorCode.ABORTED));
199+
});
200+
}
201+
182202
// we need to follow redirect so make same request with new location
183203
if ([301, 302].indexOf(res.statusCode) > -1) {
184204
debug('Redirect received %s', res.statusCode);
@@ -208,7 +228,7 @@ export class HttpAdapter implements AdapterInterface {
208228

209229
// clear cancel token to avoid memory leak
210230
if (config.cancelToken) {
211-
config.cancelToken.cancel(CANCEL_CLEAR);
231+
config.cancelToken.removeListener(cancelListener);
212232
}
213233

214234
return resolve(this.request(Object.assign({}, config, { url })));
@@ -261,28 +281,6 @@ export class HttpAdapter implements AdapterInterface {
261281
});
262282
});
263283

264-
if (config.cancelToken) {
265-
config.cancelToken
266-
.getSource()
267-
.then(reason => {
268-
// do nothing if promise is resolved by system
269-
if (reason && reason.message === CANCEL_CLEAR) {
270-
return;
271-
}
272-
273-
/* istanbul ignore next: if request is done cancel token should not throw any error */
274-
if (req) {
275-
req.abort();
276-
req = null;
277-
}
278-
279-
debug('Request canceled by user %s, config: %O', reason, config);
280-
return reject(new FsRequestError(`Request aborted. Reason: ${reason}`, config, null, FsRequestErrorCode.ABORTED));
281-
})
282-
/* istanbul ignore next: only for safety */
283-
.catch(() => {/* empty */});
284-
}
285-
286284
if (config.timeout) {
287285
req.setTimeout(config.timeout, () => {
288286
req.abort();

src/lib/request/adapters/xhr.ts

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ export class XhrAdapter implements AdapterInterface {
6969
request.timeout = config.timeout;
7070

7171
return new Promise<FsResponse>((resolve, reject) => {
72+
let cancelListener;
73+
74+
if (config.cancelToken) {
75+
cancelListener = config.cancelToken.once('cancel', (reason) => {
76+
/* istanbul ignore next: if request is done cancel token should not throw any error */
77+
if (request) {
78+
request.abort();
79+
request = null;
80+
}
81+
82+
debug('Request canceled by user %s, config: %O', reason, config);
83+
return reject(new FsRequestError(`Request aborted. Reason: ${reason}`, config, null, FsRequestErrorCode.ABORTED));
84+
});
85+
}
86+
7287
request.onreadystatechange = async () => {
7388
if (!request || request.readyState !== 4) {
7489
return;
@@ -104,7 +119,7 @@ export class XhrAdapter implements AdapterInterface {
104119

105120
// clear cancel token to avoid memory leak
106121
if (config.cancelToken) {
107-
config.cancelToken.cancel(CANCEL_CLEAR);
122+
config.cancelToken.removeListener(cancelListener);
108123
}
109124

110125
return resolve(response);
@@ -158,28 +173,6 @@ export class XhrAdapter implements AdapterInterface {
158173
}
159174
}
160175

161-
if (config.cancelToken) {
162-
config.cancelToken
163-
.getSource()
164-
.then(reason => {
165-
// do nothing if promise is resolved by system
166-
if (reason && reason.message === CANCEL_CLEAR) {
167-
return;
168-
}
169-
170-
/* istanbul ignore next: if request is done cancel token should not throw any error */
171-
if (request) {
172-
request.abort();
173-
request = null;
174-
}
175-
176-
debug('Request canceled by user %s, config: %O', reason, config);
177-
return reject(new FsRequestError(`Request aborted. Reason: ${reason}`, config, null, FsRequestErrorCode.ABORTED));
178-
})
179-
/* istanbul ignore next: only for safety */
180-
.catch(() => {/* empty */});
181-
}
182-
183176
if (data === undefined) {
184177
data = null;
185178
}

src/lib/request/token.spec.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,11 @@ describe('Request/Token', () => {
3030
});
3131

3232
describe('source token', () => {
33-
it('source token should return called', done => {
33+
it('Cancel event should be called', done => {
3434
const token = new FsCancelToken();
35-
const source = token.getSource();
3635
const cancelSpy = jest.fn().mockName('cancelSpy');
37-
const cancelSpyCatch = jest.fn().mockName('cancelSpyCatch');
38-
39-
source.then(cancelSpy).catch(cancelSpyCatch);
4036

37+
token.once('cancel', cancelSpy);
4138
token.cancel();
4239

4340
setTimeout(() => {
@@ -46,4 +43,18 @@ describe('Request/Token', () => {
4643
}, 10);
4744
});
4845
});
46+
47+
it('Cancel event should be called with reason', done => {
48+
const token = new FsCancelToken();
49+
const cancelSpy = jest.fn().mockName('cancelSpy');
50+
const cancelReason = 'test';
51+
52+
token.once('cancel', cancelSpy);
53+
token.cancel(cancelReason);
54+
55+
setTimeout(() => {
56+
expect(cancelSpy).toHaveBeenCalledWith(cancelReason);
57+
done();
58+
}, 10);
59+
});
4960
});

src/lib/request/token.ts

Lines changed: 4 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,63 +14,16 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
import { FsTokenInterface } from './types';
1817
import { EventEmitter } from 'eventemitter3';
1918

20-
// token
21-
const token = data => new Promise(resolve => data.listeners.push(resolve));
22-
23-
const tokenSource = () => {
24-
const data = {
25-
reason: null,
26-
listeners: [],
27-
};
28-
29-
const cancel = reason => {
30-
reason = reason || 'Aborted';
31-
32-
if (typeof reason === 'string') {
33-
reason = new Error(reason);
34-
}
35-
36-
data.reason = reason;
37-
38-
// Only for security reason
39-
/* istanbul ignore next */
40-
setTimeout(function() {
41-
for (let i = 0; i < data.listeners.length; i++) {
42-
if (typeof data.listeners[i] === 'function') {
43-
data.listeners[i](reason);
44-
data.listeners.splice(i, 1);
45-
}
46-
}
47-
}, 0);
48-
};
49-
50-
return {
51-
cancel: cancel,
52-
token: token(data),
53-
};
54-
};
55-
5619
/**
5720
* Filestack token that allow pause, resume or cancel given upload
5821
*
5922
* @export
6023
* @class FsToken
6124
* @extends {EventEmitter}
62-
* @implements {FsTokenInterface}
6325
*/
64-
export class FsCancelToken implements FsTokenInterface {
65-
private source: any;
66-
private cancelMethod: any;
67-
68-
constructor() {
69-
const cancelable = tokenSource();
70-
71-
this.source = cancelable.token;
72-
this.cancelMethod = cancelable.cancel;
73-
}
26+
export class FsCancelToken extends EventEmitter {
7427

7528
/**
7629
* Cancel request action
@@ -79,16 +32,9 @@ export class FsCancelToken implements FsTokenInterface {
7932
* @memberof Token
8033
*/
8134
public cancel(reason?: string | Error) {
82-
this.cancelMethod(reason);
83-
}
35+
this.emit('cancel', reason);
8436

85-
/**
86-
* Returns cancel token promise
87-
*
88-
* @returns
89-
* @memberof Token
90-
*/
91-
public getSource(): Promise<string> {
92-
return this.source;
37+
this.removeAllListeners();
9338
}
39+
9440
}

src/lib/request/types.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17+
import { FsCancelToken } from './token';
18+
1719
export enum FsHttpMethod {
1820
GET = 'GET',
1921
DELETE = 'DELETE',
@@ -32,11 +34,6 @@ export interface FsRetryConfig {
3234
retryFactor?: number;
3335
}
3436

35-
export interface FsTokenInterface {
36-
cancel: (reason?: string | Error) => void;
37-
getSource: () => Promise<any>;
38-
}
39-
4037
export interface FsAuthConfig {
4138
username: string;
4239
password: string;
@@ -69,7 +66,7 @@ export interface FsRequestOptions {
6966
filestackHeaders?: boolean;
7067
headers?: FsRequestHeaders;
7168
timeout?: number;
72-
cancelToken?: FsTokenInterface;
69+
cancelToken?: FsCancelToken;
7370
retry?: FsRetryConfig;
7471
onProgress?: (pr: ProgressEvent) => any;
7572
auth?: FsAuthConfig;

src/lib/utils/extensions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,11 @@ export const Map = {
312312
'application/vnd.anser-web-funds-transfer-initiation': ['fti'],
313313
'application/vnd.antix.game-component': ['atx'],
314314
'application/vnd.apple.installer+xml': ['mpkg'],
315-
'application/vnd.apple.keynote': ['keynote'],
315+
'application/vnd.apple.keynote': ['keynote', 'key'],
316316
'application/vnd.apple.mpegurl': ['m3u8'],
317317
'application/vnd.apple.numbers': ['numbers'],
318318
'application/vnd.apple.pages': ['pages'],
319+
'application/vnd.apple.key': ['key'],
319320
'application/vnd.apple.pkpass': ['pkpass'],
320321
'application/vnd.aristanetworks.swi': ['swi'],
321322
'application/vnd.astraea-software.iota': ['iota'],

0 commit comments

Comments
 (0)