Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,74 @@ class Sharepoint {
logAxiosError(this.debug, err, 'Unable to delete file')
}
}

/**
* Moves the specified file
* @param options An object that must contain a 'fileName' (the name of the file), 'sourcePath' (the path to a folder in
* which the file is to be moved from) and 'targetPath' (the path to a folder which the file is to be moved to) properties.
* @returns {Promise<void>}
*/
async moveFile (options) {
if (!options.fileName) {
throw new Error('You must provide a file name.')
}

checkHeaders(this.accessToken)

const sourcePath = encodeURIComponent(options.sourcePath)
const targetPath = encodeURIComponent(options.targetPath)
const fileName = encodeURIComponent(options.fileName)

const formDigestValue = await getFormDigestValue(this.siteUrl, this.accessToken)

const url = `${this.siteUrl}/_api/web/GetFileByServerRelativeUrl('${this.encodedBaseUrl}${sourcePath}/${fileName}')/moveto(newurl='${this.encodedBaseUrl}${targetPath}/${fileName}',flags=1)`

try {
await axios({
method: 'post',
url,
headers: {
Authorization: `Bearer ${this.accessToken}`,
'X-RequestDigest': formDigestValue
}
})
} catch (err) {
console.log(err)
logAxiosError(this.debug, err, 'Unable to move file')
}
}

/**
* Moves the specified file
* @param options An object that must contain a 'sourcePath' (the path to a folder in
* which the file is to be moved from) and 'targetPath' (the path to a folder which the file is to be moved to) properties.
* @returns {Promise<void>}
*/
async moveFolderContents (options) {
checkHeaders(this.accessToken)

const filesToMove = []

async function collectFilesToMove (self, sourcePath, targetPath) {
const contents = await self.getContents(sourcePath)
for (const item of contents) {
if (item.__metadata.type === 'SP.File') {
filesToMove.push({ sourcePath, targetPath, fileName: item.Name })
} else if (item.__metadata.type === 'SP.Folder') {
await collectFilesToMove(self, `${sourcePath}/${item.Name}`, `${targetPath}/${item.Name}`)
}
}
}

await collectFilesToMove(this, options.sourcePath, options.targetPath)

for (const { sourcePath, targetPath, fileName } of filesToMove) {
await this.createFolder(targetPath)
await this.moveFile({ sourcePath, targetPath, fileName })
}

await this.deleteFolder(options.sourcePath)
}
}

// based on https://axios-http.com/docs/handling_errors
Expand Down
66 changes: 66 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,72 @@ describe('tests', function () {
expect(contents.map(i => i.Name).includes(FOLDER_NAME3)).to.eql(false)
expect(contents.map(i => i.Name).includes(FOLDER_NAME4)).to.eql(false)
})

it('create and move a file', async () => {
const sourceFolderPath = `${process.env.SHAREPOINT_TESTS_DIR_PATH}/Source`
const targetFolderPath = `${process.env.SHAREPOINT_TESTS_DIR_PATH}/Target`
const fileName = 'the-file-to-move.txt'
const data = 'This file will be moved!'

await sharepoint.createFolder(sourceFolderPath)
await sharepoint.createFolder(targetFolderPath)
await sharepoint.createFile({ path: sourceFolderPath, fileName, data })

// Check contents before
const sourceFolderContentsBefore = await sharepoint.getContents(sourceFolderPath)
expect(sourceFolderContentsBefore.length).to.eql(1)
expect(sourceFolderContentsBefore[0].Name).to.eql(fileName)

const targetFolderContentsBefore = await sharepoint.getContents(targetFolderPath)
expect(targetFolderContentsBefore.length).to.eql(0)

// Move file
await sharepoint.moveFile({ sourcePath: sourceFolderPath, targetPath: targetFolderPath, fileName })

// Check contents after
const sourceFolderContentsAfter = await sharepoint.getContents(sourceFolderPath)
expect(sourceFolderContentsAfter.length).to.eql(0)

const targetFolderContentsAfter = await sharepoint.getContents(targetFolderPath)
expect(targetFolderContentsAfter.length).to.eql(1)
expect(targetFolderContentsAfter[0].Name).to.eql(fileName)

await sharepoint.deleteFolder(sourceFolderPath)
await sharepoint.deleteFolder(targetFolderPath)
})

it('create and move a folder', async () => {
const sourceFolderPath = `${process.env.SHAREPOINT_TESTS_DIR_PATH}/Source`
const targetFolderPath = `${process.env.SHAREPOINT_TESTS_DIR_PATH}/Target`

await sharepoint.createFolder(sourceFolderPath)
await sharepoint.createFolder(targetFolderPath)
await sharepoint.createFile({ path: sourceFolderPath, fileName: 'file-1.txt', data: 'File 1' })
await sharepoint.createFile({ path: sourceFolderPath, fileName: 'file-2.txt', data: 'File 2' })
await sharepoint.createFile({ path: sourceFolderPath, fileName: 'file-3.txt', data: 'File 3' })
await sharepoint.createFolder(`${sourceFolderPath}/Nested Folder`)
await sharepoint.createFile({ path: `${sourceFolderPath}/Nested Folder`, fileName: 'file-4.txt', data: 'File 4' })
await sharepoint.createFile({ path: `${sourceFolderPath}/Nested Folder`, fileName: 'file-5.txt', data: 'File 5' })

// Check contents before
const sourceFolderContentsBefore = await sharepoint.getContents(sourceFolderPath)
expect(sourceFolderContentsBefore.length).to.eql(4)

const targetFolderContentsBefore = await sharepoint.getContents(targetFolderPath)
expect(targetFolderContentsBefore.length).to.eql(0)

await sharepoint.moveFolderContents({ sourcePath: sourceFolderPath, targetPath: targetFolderPath })

// Check contents after
const sourceFolderContentsAfter = await sharepoint.getContents(sourceFolderPath)
expect(sourceFolderContentsAfter.length).to.eql(0)

const targetFolderContentsAfter = await sharepoint.getContents(targetFolderPath)
expect(targetFolderContentsAfter.length).to.eql(4)

await sharepoint.deleteFolder(sourceFolderPath)
await sharepoint.deleteFolder(targetFolderPath)
})
})
})

Expand Down