From 11810ee4b4fe136ef0b7392f8c31ade60bf8cf00 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha <dhruvitraithatha@me.com> Date: Fri, 6 Dec 2019 07:02:45 +0530 Subject: [PATCH 1/2] For #12: Add option to stream a download --- docs/SubmissionsApi.md | 28 ++++++++++++++++++++++++++++ index.js | 8 ++++---- src/SubmissionsApi.js | 10 ++++++---- src/common/helper.js | 15 ++++++++++++--- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/docs/SubmissionsApi.md b/docs/SubmissionsApi.md index b6761b8..0d2f19d 100644 --- a/docs/SubmissionsApi.md +++ b/docs/SubmissionsApi.md @@ -669,6 +669,19 @@ await submissionApiM2MClient.downloadSubmission(submissionId) await submissionApiUserCredentialsClient.downloadSubmission(submissionId) await submissionApiJwtMethodArgClient.downloadSubmission(submissionId, config.JWT) + +// Stream Model +const outputStream = fs.createWriteStream(filePath) +const req = await submissionApiM2MClient.downloadSubmission(submissionId, null, true) +req.pipe(outputStream) + +const outputStream = fs.createWriteStream(filePath) +const req = await submissionApiUserCredentialsClient.downloadSubmission(submissionId, null, true) +req.pipe(outputStream) + +const outputStream = fs.createWriteStream(filePath) +const req = await submissionApiJwtMethodArgClient.downloadSubmission(submissionId, config.JWT, true) +req.pipe(outputStream) ``` ### Demo @@ -716,6 +729,7 @@ Name | Type | Description ------------- | ------------- | ------------- **submissionId** | String | the submission id **jwt** | String | the optional json web token + **streamed** | Boolean | the optional flag indicating whether or not to return a stream instead of a promise (default is promise) ### Return type @@ -960,6 +974,19 @@ await submissionApiM2MClient.downloadArtifact(submissionId, artifactId) await submissionApiUserCredentialsClient.downloadArtifact(submissionId, artifactId) await submissionApiJwtMethodArgClient.downloadArtifact(submissionId, artifactId, config.JWT) + +// Stream Model +const outputStream = fs.createWriteStream(filePath) +const req = await submissionApiM2MClient.downloadArtifact(submissionId, artifactId, null, true) +req.pipe(outputStream) + +const outputStream = fs.createWriteStream(filePath) +const req = await submissionApiUserCredentialsClient.downloadArtifact(submissionId, artifactId, null, true) +req.pipe(outputStream) + +const outputStream = fs.createWriteStream(filePath) +const req = await submissionApiJwtMethodArgClient.downloadArtifact(submissionId, artifactId, config.JWT, true) +req.pipe(outputStream) ``` ### Demo @@ -1008,6 +1035,7 @@ Name | Type | Description **submissionId** | String | the submission id **artifactId** | String | the artifact id **jwt** | String | the optional json web token + **streamed** | Boolean | the optional flag indicating whether or not to return a stream instead of a promise (default is a promise) ### Return type diff --git a/index.js b/index.js index b5cd0a0..d26b392 100644 --- a/index.js +++ b/index.js @@ -226,8 +226,8 @@ module.exports = (allConfig) => { return require('./src/SubmissionsApi').deleteSubmission(config, submissionId, jwt) }, // Download submission - downloadSubmission: (submissionId, jwt) => { - return require('./src/SubmissionsApi').downloadSubmission(config, submissionId, jwt) + downloadSubmission: (submissionId, jwt, streamed = false) => { + return require('./src/SubmissionsApi').downloadSubmission(config, submissionId, jwt, streamed) }, // Create artifact for submission createArtifact: (submissionId, reqFormData, jwt) => { @@ -238,8 +238,8 @@ module.exports = (allConfig) => { return require('./src/SubmissionsApi').listArtifacts(config, submissionId, jwt) }, // Download artifact - downloadArtifact: (submissionId, artifactId, jwt) => { - return require('./src/SubmissionsApi').downloadArtifact(config, submissionId, artifactId, jwt) + downloadArtifact: (submissionId, artifactId, jwt, streamed = false) => { + return require('./src/SubmissionsApi').downloadArtifact(config, submissionId, artifactId, jwt, streamed) }, // Delete artifact deleteArtifact: (submissionId, artifactId, jwt) => { diff --git a/src/SubmissionsApi.js b/src/SubmissionsApi.js index f2944d8..6b94d5b 100644 --- a/src/SubmissionsApi.js +++ b/src/SubmissionsApi.js @@ -116,10 +116,11 @@ const deleteSubmission = (config, submissionId, jwt = null) => { * Function to download submission by id. * @param {Object} config Configuration object * @param {String} submissionId the submission id + * @param {Boolean} streamed Whether a stream is to be returned (Default: false) * @returns {Promise} the submission file content */ -const downloadSubmission = (config, submissionId, jwt = null) => { - return helper.reqToV5APIDownload(config, jwt, `${config.SUBMISSION_API_URL}/submissions/${submissionId}/download`) +const downloadSubmission = (config, submissionId, jwt = null, streamed = false) => { + return helper.reqToV5APIDownload(config, jwt, `${config.SUBMISSION_API_URL}/submissions/${submissionId}/download`, streamed) } /** @@ -149,10 +150,11 @@ const listArtifacts = (config, submissionId, jwt = null) => { * @param {Object} config Configuration object * @param {String} submissionId the submission id * @param {String} artifactId the artifact id + * @param {Boolean} streamed Whether a stream is to be returned (Default: false) * @returns {Promise} the artifact file content */ -const downloadArtifact = (config, submissionId, artifactId, jwt = null) => { - return helper.reqToV5APIDownload(config, jwt, `${config.SUBMISSION_API_URL}/submissions/${submissionId}/artifacts/${artifactId}/download`) +const downloadArtifact = (config, submissionId, artifactId, jwt = null, streamed = false) => { + return helper.reqToV5APIDownload(config, jwt, `${config.SUBMISSION_API_URL}/submissions/${submissionId}/artifacts/${artifactId}/download`, streamed) } /** diff --git a/src/common/helper.js b/src/common/helper.js index c8f35c7..d647ba7 100644 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -164,14 +164,23 @@ const reqToV5APIWithFile = async (config, jwt, path, formData, fileFieldName) => * Function to download file using V5 API * @param {Object} config Configuration object * @param {String} jwt The JWT - * @param (String) path Complete path of the API URL + * @param {String} path Complete path of the API URL + * @param {Boolean} streamed Whether a stream is to be returned (Default: false) * @returns {Promise} */ -const reqToV5APIDownload = async (config, jwt, path) => { +const reqToV5APIDownload = async (config, jwt, path, streamed = false) => { const token = await getToken(config, jwt) - return request + let req = request .get(path) .set('Authorization', `Bearer ${token}`) + if (streamed) { + req = req.buffer(false) + req.then = undefined + req.catch = undefined + req.finally = undefined + return req + } + return req .buffer(true) .parse(function (res, callback) { res.data = '' From e727146b130c8a928fd50d31274ccc6d808ba454 Mon Sep 17 00:00:00 2001 From: Dhruvit Raithatha <dhruvitraithatha@me.com> Date: Fri, 6 Dec 2019 12:55:03 +0530 Subject: [PATCH 2/2] Update tc-core-library-js to fix security vulnerability --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be88aa9..e44747e 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "@hapi/joi": "^15.0.3", "lodash": "^4.17.15", "superagent": "^3.8.3", - "tc-core-library-js": "appirio-tech/tc-core-library-js.git" + "tc-core-library-js": "github:appirio-tech/tc-core-library-js#v2.6.4" }, "devDependencies": { "chai": "^4.2.0",