From 66e15b83a5af6f46ec4528acfb97b8b2b5226224 Mon Sep 17 00:00:00 2001 From: meenahoda Date: Thu, 20 Jun 2024 07:33:34 +0100 Subject: [PATCH 1/5] basic implementation of download file --- lib/index.js | 23 +++++++++++++++++++++++ test/test.js | 7 +++++++ 2 files changed, 30 insertions(+) diff --git a/lib/index.js b/lib/index.js index deb7bdf..6ed6536 100644 --- a/lib/index.js +++ b/lib/index.js @@ -435,6 +435,29 @@ class Sharepoint { logAxiosError(this.debug, err, 'Unable to delete file') } } + + async downloadFile (sourcePath, targetPath) { + try { + checkHeaders(this.accessToken) + + const file = await axios.get( + `${this.siteUrl}/_layouts/15/download.aspx?sourceUrl=${this.encodedBaseUrl}${encodeURIComponent(sourcePath)}`, + { + headers: { + Authorization: `Bearer ${this.accessToken}`, + Accept: 'application/json;odata=verbose' + }, + responseType: 'stream' + } + ) + + const fileName = sourcePath.split('/').reverse()[0] + const fileStream = fs.createWriteStream(`${targetPath}/${fileName}`) + await file.data.pipe(fileStream) + } catch (err) { + console.log(err) + } + } } // based on https://axios-http.com/docs/handling_errors diff --git a/test/test.js b/test/test.js index 0c1c1a1..0ac3269 100644 --- a/test/test.js +++ b/test/test.js @@ -331,6 +331,13 @@ describe('tests', function () { expect(contents[3].Name).to.eql(FILE_NAME1) }) + it('download file 1', async () => { + await sharepoint.downloadFile( + `${process.env.SHAREPOINT_TESTS_DIR_PATH}/${FOLDER_NAME1}/${FILE_NAME1}`, + path.resolve(__dirname, 'output') + ) + }) + it('upload file of different format (png) from fixtures', async () => { const data = getBinaryData(path.resolve(__dirname, 'fixtures', BINARY_FILE_FILENAME)) From 4431479412ebfd7d9f27a0184c3f3bf9152db062 Mon Sep 17 00:00:00 2001 From: meenahoda Date: Thu, 20 Jun 2024 07:34:50 +0100 Subject: [PATCH 2/5] improve error logging --- lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 6ed6536..56f4af6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -455,7 +455,7 @@ class Sharepoint { const fileStream = fs.createWriteStream(`${targetPath}/${fileName}`) await file.data.pipe(fileStream) } catch (err) { - console.log(err) + logAxiosError(this.debug, err, 'Unable to download file') } } } From 2dbc2d4874e9e5ebd0f966988acac62ed440169e Mon Sep 17 00:00:00 2001 From: meenahoda Date: Thu, 20 Jun 2024 07:39:41 +0100 Subject: [PATCH 3/5] extend test to downloaded text file --- test/test.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 0ac3269..86185b1 100644 --- a/test/test.js +++ b/test/test.js @@ -331,11 +331,24 @@ describe('tests', function () { expect(contents[3].Name).to.eql(FILE_NAME1) }) - it('download file 1', async () => { + it('download text file', async () => { + const targetPath = path.resolve(__dirname, 'output') + + // Ensure target path exists + if (!fs.existsSync(targetPath)) { + fs.mkdirSync(targetPath) + } + + // Download file to target path await sharepoint.downloadFile( `${process.env.SHAREPOINT_TESTS_DIR_PATH}/${FOLDER_NAME1}/${FILE_NAME1}`, - path.resolve(__dirname, 'output') + targetPath ) + + // Check downloaded file content + const expectedText = await fs.readFileSync(path.join(__dirname, 'fixtures', 'Test.txt'), 'utf-8') + const downloadedText = await fs.readFileSync(path.join(targetPath, FILE_NAME1), 'utf-8') + expect(downloadedText).to.eql(expectedText) }) it('upload file of different format (png) from fixtures', async () => { From 4b503f0c04e8ddf8b62b1d2da6def8890a1f9ee5 Mon Sep 17 00:00:00 2001 From: meenahoda Date: Thu, 20 Jun 2024 07:43:10 +0100 Subject: [PATCH 4/5] test download binary file --- test/test.js | 60 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/test/test.js b/test/test.js index 86185b1..dd679cb 100644 --- a/test/test.js +++ b/test/test.js @@ -331,26 +331,6 @@ describe('tests', function () { expect(contents[3].Name).to.eql(FILE_NAME1) }) - it('download text file', async () => { - const targetPath = path.resolve(__dirname, 'output') - - // Ensure target path exists - if (!fs.existsSync(targetPath)) { - fs.mkdirSync(targetPath) - } - - // Download file to target path - await sharepoint.downloadFile( - `${process.env.SHAREPOINT_TESTS_DIR_PATH}/${FOLDER_NAME1}/${FILE_NAME1}`, - targetPath - ) - - // Check downloaded file content - const expectedText = await fs.readFileSync(path.join(__dirname, 'fixtures', 'Test.txt'), 'utf-8') - const downloadedText = await fs.readFileSync(path.join(targetPath, FILE_NAME1), 'utf-8') - expect(downloadedText).to.eql(expectedText) - }) - it('upload file of different format (png) from fixtures', async () => { const data = getBinaryData(path.resolve(__dirname, 'fixtures', BINARY_FILE_FILENAME)) @@ -380,6 +360,46 @@ describe('tests', function () { }) }) + it('download text file', async () => { + const targetPath = path.resolve(__dirname, 'output') + + // Ensure target path exists + if (!fs.existsSync(targetPath)) { + fs.mkdirSync(targetPath) + } + + // Download file to target path + await sharepoint.downloadFile( + `${process.env.SHAREPOINT_TESTS_DIR_PATH}/${FOLDER_NAME1}/${FILE_NAME1}`, + targetPath + ) + + // Check downloaded file content + const expectedFile = await fs.readFileSync(path.join(__dirname, 'fixtures', 'Test.txt'), 'utf-8') + const downloadedFile = await fs.readFileSync(path.join(targetPath, FILE_NAME1), 'utf-8') + expect(downloadedFile).to.eql(expectedFile) + }) + + it('download binary file', async () => { + const targetPath = path.resolve(__dirname, 'output') + + // Ensure target path exists + if (!fs.existsSync(targetPath)) { + fs.mkdirSync(targetPath) + } + + // Download file to target path + await sharepoint.downloadFile( + `${process.env.SHAREPOINT_TESTS_DIR_PATH}/${FOLDER_NAME1}/${BINARY_FILE_FILENAME}`, + targetPath + ) + + // Check downloaded file content + const expectedFile = await fs.readFileSync(path.join(__dirname, 'fixtures', 'Test.png'), 'utf-8') + const downloadedFile = await fs.readFileSync(path.join(targetPath, BINARY_FILE_FILENAME), 'utf-8') + expect(downloadedFile).to.eql(expectedFile) + }) + it('delete folder 1', async () => { await sharepoint.deleteFolder(`${process.env.SHAREPOINT_TESTS_DIR_PATH}/${FOLDER_NAME1}`) }) From 5a82e4f77f80b533919a1d4871c20c6b6c2c3f93 Mon Sep 17 00:00:00 2001 From: meenahoda Date: Thu, 20 Jun 2024 07:45:06 +0100 Subject: [PATCH 5/5] add doc --- lib/index.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/index.js b/lib/index.js index 56f4af6..36424ba 100644 --- a/lib/index.js +++ b/lib/index.js @@ -436,6 +436,12 @@ class Sharepoint { } } + /** + * Download the specified file + * @param sourcePath path to the file to download + * @param targetPath path to where to download the file to + * @returns {Promise} + */ async downloadFile (sourcePath, targetPath) { try { checkHeaders(this.accessToken)