Skip to content

Commit 96fc069

Browse files
Buffer upload in assets (#303)
* Added buffer upload in assets * Fixed linting erros * axios version bump * Downgraded version
1 parent 2b1f913 commit 96fc069

File tree

6 files changed

+93
-7
lines changed

6 files changed

+93
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## [v1.19.6](https://github.com/contentstack/contentstack-management-javascript/tree/v1.19.6) (2025-03-31)
4+
- Enhancement
5+
- Added buffer upload in assets
6+
37
## [v1.19.5](https://github.com/contentstack/contentstack-management-javascript/tree/v1.19.5) (2025-03-17)
48
- Fix
59
- Added AuditLog in the stack class

lib/stack/asset/index.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,11 +291,21 @@ export function createFormData (data) {
291291
if (typeof data.title === 'string') {
292292
formData.append('asset[title]', data.title)
293293
}
294-
const uploadStream = createReadStream(data.upload)
295-
if (typeof data.content_type === 'string') {
296-
formData.append('asset[upload]', uploadStream, { contentType: data.content_type })
294+
// Handle Buffer Upload
295+
if (Buffer.isBuffer(data.upload)) {
296+
formData.append('asset[upload]', data.upload, {
297+
filename: data.filename || 'uploaded_file',
298+
contentType: data.content_type || 'application/octet-stream'
299+
})
300+
} else if (typeof data.upload === 'string') { // Handle File Path Upload
301+
const uploadStream = createReadStream(data.upload)
302+
if (typeof data.content_type === 'string') {
303+
formData.append('asset[upload]', uploadStream, { contentType: data.content_type })
304+
} else {
305+
formData.append('asset[upload]', uploadStream)
306+
}
297307
} else {
298-
formData.append('asset[upload]', uploadStream)
308+
throw new Error('Invalid upload format. Must be a file path or Buffer.')
299309
}
300310
return formData
301311
}

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
"author": "Contentstack",
5353
"license": "MIT",
5454
"dependencies": {
55-
"axios": "^1.8.2",
55+
"axios": "^1.8.3",
5656
"form-data": "^4.0.2",
5757
"lodash": "^4.17.21",
5858
"qs": "^6.14.0"

test/sanity-check/api/asset-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import fs from 'fs'
12
import path from 'path'
23
import { expect } from 'chai'
34
import { describe, it, setup } from 'mocha'
@@ -39,6 +40,31 @@ describe('Assets api Test', () => {
3940
.catch(done)
4041
})
4142

43+
it('should upload asset from buffer', (done) => {
44+
const filePath = path.join(__dirname, '../mock/customUpload.html')
45+
const fileBuffer = fs.readFileSync(filePath) // Read file into Buffer
46+
const asset = {
47+
upload: fileBuffer, // Buffer upload
48+
filename: 'customUpload.html', // Ensure filename is provided
49+
content_type: 'text/html', // Set content type
50+
title: 'buffer-asset',
51+
description: 'Buffer Asset Desc',
52+
tags: ['Buffer']
53+
}
54+
makeAsset().create(asset)
55+
.then((asset) => {
56+
jsonWrite(asset, 'bufferAsset.json')
57+
expect(asset.uid).to.be.not.equal(null)
58+
expect(asset.url).to.be.not.equal(null)
59+
expect(asset.filename).to.be.equal('customUpload.html')
60+
expect(asset.title).to.be.equal('buffer-asset')
61+
expect(asset.description).to.be.equal('Buffer Asset Desc')
62+
expect(asset.content_type).to.be.equal('text/html')
63+
done()
64+
})
65+
.catch(done)
66+
})
67+
4268
it('should download asset from URL.', done => {
4369
makeAsset().download({ url: assetURL, responseType: 'stream' })
4470
.then((response) => {

test/unit/asset-test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import fs from 'fs'
12
import path from 'path'
23
import Axios from 'axios'
34
import { expect } from 'chai'
@@ -171,6 +172,49 @@ describe('Contentstack Asset test', () => {
171172
.catch(done)
172173
})
173174

175+
it('should upload asset from buffer', (done) => {
176+
const mock = new MockAdapter(Axios)
177+
mock.onPost('/assets').reply(200, {
178+
asset: {
179+
uid: 'mock-uid',
180+
url: '/assets',
181+
filename: 'customUpload.html',
182+
title: 'buffer-asset',
183+
description: 'Buffer Asset Desc',
184+
content_type: 'text/html',
185+
tags: ['Buffer'],
186+
parent_uid: 'UID'
187+
}
188+
})
189+
const filePath = path.join(__dirname, '../api/mock/customUpload.html')
190+
const fileBuffer = fs.readFileSync(filePath)
191+
const assetUpload = {
192+
upload: fileBuffer, // Buffer upload
193+
filename: 'customUpload.html', // Filename to identify the file
194+
content_type: 'text/html', // MIME type
195+
title: 'buffer-asset',
196+
description: 'Buffer Asset Desc',
197+
tags: ['Buffer'],
198+
parent_uid: 'UID'
199+
}
200+
const form = createFormData(assetUpload)() // Create FormData for Buffer upload
201+
const boundary = form.getBoundary()
202+
expect(boundary).to.be.equal(form.getBoundary())
203+
expect(boundary.length).to.be.greaterThan(30)
204+
makeAsset()
205+
.create(assetUpload)
206+
.then((asset) => {
207+
expect(asset.uid).to.be.equal('mock-uid')
208+
expect(asset.filename).to.be.equal('customUpload.html')
209+
expect(asset.title).to.be.equal('buffer-asset')
210+
expect(asset.description).to.be.equal('Buffer Asset Desc')
211+
expect(asset.content_type).to.be.equal('text/html')
212+
expect(asset.tags).to.include('Buffer')
213+
done()
214+
})
215+
.catch(done)
216+
})
217+
174218
it('Asset replace test', done => {
175219
var mock = new MockAdapter(Axios)
176220
mock.onPut('/assets/UID').reply(200, {

0 commit comments

Comments
 (0)