Skip to content

Commit 4c0b8b5

Browse files
committed
Asset download functionality added
1 parent c213ca5 commit 4c0b8b5

File tree

9 files changed

+118
-23
lines changed

9 files changed

+118
-23
lines changed

lib/contentstack.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@ import httpClient from './core/contentstackHTTPClient.js'
3434
* import * as contentstack from '@contentstack/management'
3535
* const client = contentstack.client({ headers: { 'headerkey': 'value'} })
3636
*
37-
*
3837
* @prop {string=} params.authtoken - Optional Authtoken is a read-write token used to make authorized CMA requests, but it is a user-specific token.
3938
* @example //Set the `authtoken`
4039
* import * as contentstack from '@contentstack/management'
4140
* const client = contentstack.client({ authtoken: 'value' })
42-
*
41+
*
4342
* @prop {string=} params.timeout - Optional authorization token is a read-write token used to make authorized CMA requests, but it is a user-specific token.
4443
* @example //Set the `authorization`
4544
* import * as contentstack from '@contentstack/management'
4645
* const client = contentstack.client({ authorization: 'Bearer <token_value>' })
47-
*
46+
*
4847
* @prop {number=} params.timeout - Optional number of milliseconds before the request times out. Default is 30000ms
4948
* @example //Set the `timeout` to 50000ms
5049
* import * as contentstack from '@contentstack/management'

lib/stack/asset/index.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,52 @@ export function Asset (http, data = {}) {
217217
* import * as contentstack from '@contentstack/management'
218218
* const client = contentstack.client()
219219
*
220-
* client.stack().asset().query({ query: { filename: 'Asset Name' } }).find()
220+
* client.stack({ api_key: 'api_key'}).asset().query({ query: { filename: 'Asset Name' } }).find()
221221
* .then((asset) => console.log(asset))
222222
*/
223223
this.query = query({ http: http, wrapperCollection: AssetCollection })
224224
}
225+
/**
226+
* @description The Download function will get downloadable file in specified format.
227+
* @memberof Asset
228+
* @func download
229+
* @returns {Array<AssetResponse>} Array of Asset.
230+
* @param {*} param.url The url for the asset to download
231+
* @param {*} param.responseType Optional parameter to specify the response type.
232+
* @example
233+
*
234+
* import * as contentstack from '@contentstack/management'
235+
* const client = contentstack.client()
236+
*
237+
* client.stack({ api_key: 'api_key'}).asset('uid').fetch()
238+
* .then((asset) => asset.download({responseType: 'blob'}))
239+
* .then((response) => // Write response data to destination file. )
240+
* @example
241+
*
242+
* import * as contentstack from '@contentstack/management'
243+
* const client = contentstack.client()
244+
*
245+
* client.stack({ api_key: 'api_key'}).asset().download({url: 'asset_url_to_download', responseType: 'blob'})
246+
* .then((response) => // Write response data to destination file. )
247+
*/
248+
this.download = async function ({ url, responseType, params }) {
249+
try {
250+
const headers = {
251+
headers: {
252+
...params,
253+
...cloneDeep(this.stackHeaders)
254+
},
255+
responseType
256+
} || { responseType }
257+
const requestUrl = url || this.url
258+
if (!requestUrl || requestUrl === undefined) {
259+
throw new Error('Asset URL can not be empty')
260+
}
261+
return http.get(requestUrl, headers)
262+
} catch (err) {
263+
throw error(err)
264+
}
265+
}
225266
return this
226267
}
227268

lib/stack/contentType/entry/index.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,22 +198,22 @@ export function Entry (http, data) {
198198
* const client = contentstack.client()
199199
*
200200
* const workflow_stage = {
201-
* "comment": "Workflow Comment",
202-
* "due_date": "Thu Dec 01 2018",
203-
* "notify": false,
204-
* "uid": "workflow_stage_uid",
205-
* "assigned_to": [{
206-
* "uid": "user_uid",
207-
* "name": "Username",
208-
* "email": "user_email_id"
209-
* }],
210-
* "assigned_by_roles": [{
211-
* "uid": "role_uid",
212-
* "name": "Role name"
213-
* }]
214-
* }
201+
* "comment": "Workflow Comment",
202+
* "due_date": "Thu Dec 01 2018",
203+
* "notify": false,
204+
* "uid": "workflow_stage_uid",
205+
* "assigned_to": [{
206+
* "uid": "user_uid",
207+
* "name": "Username",
208+
* "email": "user_email_id"
209+
* }],
210+
* "assigned_by_roles": [{
211+
* "uid": "role_uid",
212+
* "name": "Role name"
213+
* }]
214+
* }
215215
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry('uid').publishRequest({ publishing_rule, locale: 'en-us'})
216-
* .then((response) => console.log(response.notice))
216+
* .then((response) => console.log(response.notice));
217217
*/
218218
this.setWorkflowStage = async ({workflow_stage, locale}) => {
219219
const publishDetails = {
@@ -291,7 +291,7 @@ export function Entry (http, data) {
291291
* client.stack({ api_key: 'api_key'}).contentType('content_type_uid').entry()
292292
* .import({
293293
* entry: 'path/to/file.json',
294-
* overright: true
294+
* overwrite: true
295295
* })
296296
* .then((entry) => console.log(entry))
297297
*

test/api/asset-test.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path'
22
import { expect } from 'chai'
33
import { describe, it, setup } from 'mocha'
4-
import { jsonReader } from '../utility/fileOperations/readwrite'
4+
import { jsonReader, writeDownloadedFile } from '../utility/fileOperations/readwrite'
55
import { contentstackClient } from '../utility/ContentstackClient.js'
66

77
var client = {}
@@ -10,6 +10,7 @@ var stack = {}
1010
var folderUID = ''
1111
var assetUID = ''
1212
var publishAssetUID = ''
13+
var assetURL = ''
1314
describe('Assets api Test', () => {
1415
setup(() => {
1516
const user = jsonReader('loggedinuser.json')
@@ -27,6 +28,7 @@ describe('Assets api Test', () => {
2728
makeAsset().create(asset)
2829
.then((asset) => {
2930
assetUID = asset.uid
31+
assetURL = asset.url
3032
expect(asset.uid).to.be.not.equal(null)
3133
expect(asset.url).to.be.not.equal(null)
3234
expect(asset.filename).to.be.equal('customUpload.html')
@@ -38,6 +40,22 @@ describe('Assets api Test', () => {
3840
.catch(done)
3941
})
4042

43+
it('Download asset from URL.', done => {
44+
makeAsset().download({ url: assetURL, responseType: 'stream' })
45+
.then((response) => {
46+
writeDownloadedFile(response, 'asset1')
47+
done()
48+
}).catch(done)
49+
})
50+
it('Download asset from fetch details ', done => {
51+
makeAsset(assetUID).fetch()
52+
.then((asset) => asset.download({ responseType: 'stream' }))
53+
.then((response) => {
54+
writeDownloadedFile(response, 'asset2')
55+
done()
56+
}).catch(done)
57+
})
58+
4159
it('Create folder ', done => {
4260
makeAsset().folder().create({ asset: { name: 'Sample Folder' } })
4361
.then((asset) => {

test/typescript/asset.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from "path";
44
var assetUID = ''
55
var folderUID = ''
66
var publishAssetUID = ''
7-
7+
var assetURL = ''
88
export function createAsset(stack: Stack) {
99
describe('Asset create', () => {
1010
test('Asset Upload', done => {
@@ -17,6 +17,7 @@ export function createAsset(stack: Stack) {
1717
stack.asset().create(asset)
1818
.then((asset) => {
1919
assetUID = asset.uid
20+
assetURL = asset.url
2021
expect(asset.uid).to.be.not.equal(null)
2122
expect(asset.url).to.be.not.equal(null)
2223
expect(asset.filename).to.be.equal('customUpload.html')
@@ -67,6 +68,27 @@ export function createAsset(stack: Stack) {
6768
})
6869
}
6970

71+
export function downloadAsset(stack: Stack) {
72+
describe('Asset download', () => {
73+
test('Download asset from url', done => {
74+
stack.asset().download({url: assetURL, responseType: 'stream'})
75+
.then((_) => {
76+
done()
77+
})
78+
.catch(done)
79+
})
80+
81+
test('Download asset from uid', done => {
82+
stack.asset(assetUID).fetch()
83+
.then((asset) => asset.download({responseType: 'stream'}))
84+
.then((_) => {
85+
done()
86+
})
87+
.catch(done)
88+
})
89+
})
90+
}
91+
7092
export function replaceAsset(stack: Stack) {
7193
describe('Asset replace', () => {
7294
test('Replace Asset', done => {

test/typescript/index.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as dotenv from 'dotenv'
55
import { shareStack, stacks, stackTest, unshareStack } from './stack';
66
import { contentType, createContentType, queryContentType } from './contentType';
77
import { createEntry, getEntries, importEntry, publishUnpublishEntry } from './entry';
8-
import { createAsset, deleteAsset, getAssets, publishUnpublishAsset, queryOnAsset, replaceAsset } from './asset';
8+
import { createAsset, deleteAsset, downloadAsset, getAssets, publishUnpublishAsset, queryOnAsset, replaceAsset } from './asset';
99
import { createGlobalField, globalField, queryGlobalField } from './globalField';
1010
import { createBranch, deleteBranch, queryBranch } from './branch';
1111
import { createBranchAlias, deleteBranchAlias, queryBranchAlias } from './branchAlias';
@@ -76,6 +76,7 @@ describe('Typescript API test', () => {
7676
importEntry(stack)
7777

7878
createAsset(stack)
79+
downloadAsset(stack)
7980
replaceAsset(stack)
8081
getAssets(stack)
8182
publishUnpublishAsset(stack)

test/utility/fileOperations/readwrite.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ function ensureDirectoryExistence (filePath) {
2727
fs.mkdirSync(dirname)
2828
}
2929
}
30+
31+
export function writeDownloadedFile (response, fileName) {
32+
const filePath = path.resolve(dataFiles, fileName)
33+
ensureDirectoryExistence(`${dataFiles}${fileName}`)
34+
response.data.pipe(fs.createWriteStream(filePath))
35+
}

types/contentstackCollection.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ export interface EntryCollection<T> extends ContentstackCollection<T> {
1111
schema?: object
1212
content_Type?: object
1313
}
14+
15+
export type AssetResponseType =
16+
| 'arraybuffer'
17+
| 'blob'
18+
| 'stream';

types/stack/asset/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { AssetResponseType } from "../../contentstackCollection";
12
import { AnyProperty, SystemFields } from "../../utility/fields";
23
import { Queryable, SystemFunction } from "../../utility/operations";
34
import { Publishable } from "../../utility/publish";
@@ -6,11 +7,13 @@ import { Folder, Folders } from "./folder";
67

78
export interface Asset extends Publishable, Unpublishable, SystemFields, SystemFunction<Asset> {
89
replace(param: AssetData): Promise<Asset>
10+
download(data: {responseType: AssetResponseType, param?: AnyProperty}): Promise<any>
911
}
1012

1113
export interface Assets extends Queryable<Asset, AssetData> {
1214
folder(): Folders
1315
folder(uid: string): Folder
16+
download(data: {url: string, responseType: AssetResponseType, param?: AnyProperty}): Promise<any>
1417
}
1518

1619
export interface AssetData extends AnyProperty {

0 commit comments

Comments
 (0)