Skip to content

Commit 5ed6afd

Browse files
authored
feat(download): Add download file method (#415)
* feat(file.download): add download method for FileApi
1 parent 3170f29 commit 5ed6afd

File tree

11 files changed

+105
-32
lines changed

11 files changed

+105
-32
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
### [3.21.1](https://github.com/filestack/filestack-js/compare/v3.21.0...v3.21.1) (2021-01-25)
6+
7+
8+
### Bug Fixes
9+
10+
* **picker:** fix accept option in picker, bump version to 1.20.1 ([7e48a30](https://github.com/filestack/filestack-js/commit/7e48a307f898a40f131e2b72c188adc3c259bab5))
11+
512
## [3.21.0](https://github.com/filestack/filestack-js/compare/v3.20.0...v3.21.0) (2021-01-13)
613

714

manual_tests/request.ts

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,30 @@
1515
* See the License for the specific language governing permissions and
1616
* limitations under the License.
1717
*/
18-
const nock = require('nock');
18+
// const nock = require('nock');
1919
import { FsRequest } from './../src/lib/request/index';
20-
import { FsCancelToken } from './../src/lib/request/token';
20+
// import { FsCancelToken } from './../src/lib/request/token';
2121

22-
nock('http://www.filestacktest.com')
23-
.get('/123')
24-
.once()
25-
// .delay(1000)
26-
.reply(404, '<html></html>', { 'content-type': 'text/plain' })
27-
.get('/123')
28-
.reply(200, '<html></html>', { 'content-type': 'text/plain' });
22+
// nock('http://www.filestacktest.com')
23+
// .get('/123')
24+
// .once()
25+
// // .delay(1000)
26+
// .reply(404, '<html></html>', { 'content-type': 'text/plain' })
27+
// .get('/123')
28+
// .reply(200, '<html></html>', { 'content-type': 'text/plain' });
2929

30-
const token = new FsCancelToken();
30+
// const token = new FsCancelToken();
3131

3232
// setTimeout(() => {
3333
// token.cancel();
3434
// }, 1000);
3535

36-
FsRequest.get('http://www.filestacktest.com/123', {
37-
cancelToken: token,
38-
timeout: 500,
39-
retry: {
40-
retry: 2,
41-
retryFactor: 2,
42-
retryMaxTime: 1500,
43-
},
36+
FsRequest.get('https://cdn.filestackcontent.com/llIbWqvRX25JPxCBqkoV', {
37+
// cancelToken: token,
38+
// timeout: 500,
4439
}).then((resp) => {
45-
console.log('Response:', resp);
40+
console.log('Response:', resp.data);
41+
console.log(resp.data.file.length);
4642
}).catch((e) => {
4743
console.error('Catch Errror', e);
4844
});

package-lock.json

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

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "filestack-js",
3-
"version": "3.21.0",
3+
"version": "3.21.1",
44
"description": "Official JavaScript library for Filestack",
55
"main": "build/main/index.js",
66
"module": "build/module/index.js",
@@ -54,7 +54,7 @@
5454
"lodash.clonedeep": "^4.5.0",
5555
"p-queue": "^4.0.0",
5656
"spark-md5": "^3.0.0",
57-
"ts-node": "^8.10.1"
57+
"ts-node": "^8.10.2"
5858
},
5959
"devDependencies": {
6060
"@babel/core": "^7.8.4",

scripts/publish.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const pushOneFileToS3 = (basePath, to, cacheControll = 1) => {
3333
Bucket: to.bucket,
3434
Key: uploadKey,
3535
Body: content,
36-
CacheControl: `max-age=${cacheControll * 60 * 60 * 24}` || 'max-age=86400',
36+
CacheControl: `max-age=${cacheControllDays * 60 * 60 * 24}` || 'max-age=86400',
3737
ContentType: figureOutFileMimetype(basePath),
3838
};
3939

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.20.0';
21+
const PICKER_VERSION = '1.20.1';
2222

2323
/**
2424
* @private

src/lib/api/file.spec.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@
3131
* limitations under the License.
3232
*/
3333

34-
import { retrieve, remove, metadata } from './file';
34+
import { retrieve, remove, metadata, download } from './file';
3535
import { FsRequest } from './../request';
3636
import { Session } from '../client';
3737
import { config } from './../../config';
3838

3939
jest.mock('./../request');
40-
jest.mock('./../filelink');
40+
// jest.mock('./../filelink');
4141

4242
const mockedSession: Session = {
4343
apikey: 'fakeApikey',
@@ -95,6 +95,19 @@ describe('FileAPI', () => {
9595
});
9696
});
9797

98+
describe('Download', () => {
99+
it('should return buffer on download request', async () => {
100+
const testResp = Buffer.from('123');
101+
const methodMocked = jest.fn(() => Promise.resolve(testResp));
102+
103+
// @ts-ignore
104+
FsRequest.dispatch.mockImplementation(methodMocked);
105+
const resp = await download(mockedSession, 'gNDNCDWNTKqoGFISdd2A');
106+
107+
expect(resp).toEqual(testResp);
108+
});
109+
});
110+
98111
describe('Remove', () => {
99112
it('should call remove', async () => {
100113
const deleteMocked = jest.fn(() => Promise.resolve({ data: {} }));

src/lib/api/file.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
*/
1717

1818
import { Security, Session } from '../client';
19+
import { Filelink } from './../filelink';
1920
import { removeEmpty } from '../utils';
21+
import { FsResponse } from './../request/types';
2022
import { FilestackError } from './../../filestack_error';
2123
import { getValidator, MetadataParamsSchema, RetrieveParamsSchema } from './../../schema';
2224
import { FsRequest, FsHttpMethod } from '../request';
@@ -105,12 +107,31 @@ export const metadata = (session: Session, handle?: string, opts?: MetadataOptio
105107

106108
const baseURL = `${session.urls.fileApiUrl}/${handle}/metadata`;
107109
return new Promise((resolve, reject) => {
108-
FsRequest.get(baseURL, { params: removeEmpty(options), filestackHeaders: false, })
110+
FsRequest.get(baseURL, { params: removeEmpty(options), filestackHeaders: false })
109111
.then(res => resolve({ ...res.data, handle }))
110112
.catch(reject);
111113
});
112114
};
113115

116+
/**
117+
* Download file to blob or buffer format
118+
*
119+
* @param session
120+
* @param handle
121+
*/
122+
export const download = (session: Session, handle: string, security?: Security): Promise<FsResponse> => {
123+
const fl = new Filelink(handle, session.apikey);
124+
125+
const policy = (security && security.policy) || session.policy;
126+
const signature = (security && security.signature) || session.signature;
127+
128+
if (policy && signature) {
129+
fl.security({ signature, policy });
130+
}
131+
132+
return FsRequest.dispatch(fl.toString(), { method: FsHttpMethod.GET, blobResponse: true });
133+
};
134+
114135
export interface RetrieveOptions {
115136
metadata?: boolean;
116137
head?: boolean;
@@ -123,6 +144,7 @@ export interface RetrieveOptions {
123144
* Returns file information
124145
*
125146
* @private
147+
* @deprecated
126148
* @param session
127149
* @param handle
128150
* @param options
@@ -133,6 +155,8 @@ export const retrieve = (session: Session, handle: string, options: RetrieveOpti
133155
throw new FilestackError('File handle is required');
134156
}
135157

158+
console.info('Retrieve method is deprecated and it will be removed. Please use metadata or download');
159+
136160
const validateRes = getValidator(RetrieveParamsSchema)(options);
137161

138162
if (validateRes.errors.length) {

src/lib/client.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ import { EventEmitter } from 'eventemitter3';
1919
import * as Sentry from '@sentry/minimal';
2020
import { config, Hosts } from '../config';
2121
import { FilestackError } from './../filestack_error';
22-
import { metadata, MetadataOptions, remove, retrieve, RetrieveOptions } from './api/file';
22+
import { metadata, MetadataOptions, remove, retrieve, RetrieveOptions, download } from './api/file';
2323
import { transform, TransformOptions } from './api/transform';
2424
import { storeURL } from './api/store';
2525
import * as Utils from './utils';
2626
import { Upload, InputFile, UploadOptions, StoreUploadOptions, UploadTags } from './api/upload';
2727
import { preview, PreviewOptions } from './api/preview';
2828
import { CloudClient } from './api/cloud';
2929
import { Prefetch, PrefetchResponse, PrefetchOptions } from './api/prefetch';
30+
import { FsResponse } from './request/types';
3031
import { StoreParams } from './filelink';
3132

3233
import { picker, PickerInstance, PickerOptions } from './picker';
@@ -343,6 +344,7 @@ export class Client extends EventEmitter {
343344
* ```
344345
*
345346
* @see [File API - Download](https://www.filestack.com/docs/api/file#download)
347+
* @deprecated use metadata or download methods instead
346348
* @param handle Valid file handle
347349
* @param options RetrieveOptions
348350
* @param security Optional security override.
@@ -353,6 +355,31 @@ export class Client extends EventEmitter {
353355
return retrieve(this.session, handle, options, security);
354356
}
355357

358+
/**
359+
* Download file by handle
360+
*
361+
*
362+
* ### Browser Example
363+
*
364+
* ```js
365+
* client.download('fileHandle').then((response) => {
366+
* const img = new Image();
367+
* img.src = URL.createObjectURL(res.data)
368+
* document.body.appendChild(img);
369+
* }).catch((err) => {
370+
* console.error(err);
371+
* })
372+
* ```
373+
*
374+
* @see [File API - Download](https://www.filestack.com/docs/api/file#download)
375+
* @param handle Valid file handle
376+
* @throws Error
377+
*/
378+
download(handle: string, security?: Security): Promise<FsResponse> {
379+
/* istanbul ignore next */
380+
return download(this.session, handle, security);
381+
}
382+
356383
/**
357384
* Interface to the Filestack [Processing API](https://www.filestack.com/docs/api/processing).
358385
* Convert a URL, handle, or storage alias to another URL which links to the transformed file.

src/lib/request/adapters/xhr.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export class XhrAdapter implements AdapterInterface {
4444

4545
let request = new XMLHttpRequest();
4646

47+
if (config.blobResponse) {
48+
request.responseType = 'blob';
49+
}
50+
4751
// HTTP basic authentication
4852
if (config.auth) {
4953
if (!config.auth.username || config.auth.username.length === 0 || !config.auth.password || config.auth.password.length === 0) {

0 commit comments

Comments
 (0)