mirror of
https://github.com/sasjs/adapter.git
synced 2026-04-21 05:01:31 +00:00
Merge pull request #190 from sasjs/issue-186
feat: listFolder and improvements
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+227
-172
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+31
-24
File diff suppressed because one or more lines are too long
+45
-236
File diff suppressed because one or more lines are too long
+76
-14
@@ -1130,8 +1130,14 @@ export class SASViyaApiClient {
|
|||||||
return uploadedFiles
|
return uploadedFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getFolderUri(folderPath: string, accessToken?: string) {
|
private async getFolderDetails(
|
||||||
const url = '/folders/folders/@item?path=' + folderPath
|
folderPath: string,
|
||||||
|
accessToken?: string
|
||||||
|
): Promise<Folder | undefined> {
|
||||||
|
const url = isUri(folderPath)
|
||||||
|
? folderPath
|
||||||
|
: `/folders/folders/@item?path=${folderPath}`
|
||||||
|
|
||||||
const { result: folder } = await this.requestClient
|
const { result: folder } = await this.requestClient
|
||||||
.get<Folder>(`${this.serverUrl}${url}`, accessToken)
|
.get<Folder>(`${this.serverUrl}${url}`, accessToken)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@@ -1139,7 +1145,15 @@ export class SASViyaApiClient {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if (!folder) return undefined
|
if (!folder) return undefined
|
||||||
return `/folders/folders/${folder.id}`
|
return folder
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getFolderUri(folderPath: string, accessToken?: string) {
|
||||||
|
const folderDetails = await this.getFolderDetails(folderPath, accessToken)
|
||||||
|
|
||||||
|
if (!folderDetails) return undefined
|
||||||
|
|
||||||
|
return `/folders/folders/${folderDetails.id}`
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getRecycleBinUri(accessToken: string) {
|
private async getRecycleBinUri(accessToken: string) {
|
||||||
@@ -1188,9 +1202,44 @@ export class SASViyaApiClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves a Viya folder to a new location. The folder may be renamed at the same time.
|
* Lists children folders for given Viya folder.
|
||||||
|
* @param sourceFolder - the full path (eg `/Public/example/myFolder`) or URI of the source folder listed. Providing URI instead of path will save one extra request.
|
||||||
|
* @param accessToken - an access token for authorizing the request.
|
||||||
|
*/
|
||||||
|
public async listFolder(
|
||||||
|
sourceFolder: string,
|
||||||
|
accessToken?: string,
|
||||||
|
limit: number = 20
|
||||||
|
) {
|
||||||
|
// checks if 'sourceFolder' is already a URI
|
||||||
|
const sourceFolderUri = isUri(sourceFolder)
|
||||||
|
? sourceFolder
|
||||||
|
: await this.getFolderUri(sourceFolder, accessToken)
|
||||||
|
|
||||||
|
const requestInfo = {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer ' + accessToken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { result: members } = await this.requestClient.get<{ items: any[] }>(
|
||||||
|
`${this.serverUrl}${sourceFolderUri}/members?limit=${limit}`,
|
||||||
|
accessToken
|
||||||
|
)
|
||||||
|
|
||||||
|
if (members && members.items) {
|
||||||
|
return members.items.map((item: any) => item.name)
|
||||||
|
} else {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves Viya folder to a new location. The folder may be renamed at the same time.
|
||||||
* @param sourceFolder - the full path (eg `/Public/example/myFolder`) or URI of the source folder to be moved. Providing URI instead of path will save one extra request.
|
* @param sourceFolder - the full path (eg `/Public/example/myFolder`) or URI of the source folder to be moved. Providing URI instead of path will save one extra request.
|
||||||
* @param targetParentFolder - the full path or URI of the _parent_ folder to which the `sourceFolder` will be moved (eg `/Public/newDestination`). To move a folder, a user has to have write permissions in targetParentFolder. Providing URI instead of path will save one extra request.
|
* @param targetParentFolder - the full path or URI of the _parent_ folder to which the `sourceFolder` will be moved (eg `/Public/newDestination`). To move a folder, a user has to have write permissions in targetParentFolder. Providing URI instead of the path will save one extra request.
|
||||||
* @param targetFolderName - the name of the "moved" folder. If left blank, the original folder name will be used (eg `myFolder` in `/Public/newDestination/myFolder` for the example above). Optional field.
|
* @param targetFolderName - the name of the "moved" folder. If left blank, the original folder name will be used (eg `myFolder` in `/Public/newDestination/myFolder` for the example above). Optional field.
|
||||||
* @param accessToken - an access token for authorizing the request.
|
* @param accessToken - an access token for authorizing the request.
|
||||||
*/
|
*/
|
||||||
@@ -1200,22 +1249,35 @@ export class SASViyaApiClient {
|
|||||||
targetFolderName: string,
|
targetFolderName: string,
|
||||||
accessToken: string
|
accessToken: string
|
||||||
) {
|
) {
|
||||||
// checks if 'sourceFolder' is already a URI
|
// If target path is an existing folder, than keep source folder name, othervise rename it with given target folder name
|
||||||
const sourceFolderUri = isUri(sourceFolder)
|
const sourceFolderName = sourceFolder.split('/').pop() as string
|
||||||
? sourceFolder
|
const targetFolderDetails = await this.getFolderDetails(
|
||||||
: await this.getFolderUri(sourceFolder, accessToken)
|
targetParentFolder,
|
||||||
|
accessToken
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!targetFolderDetails) {
|
||||||
|
let targetParentFolderArr = targetParentFolder.split('/')
|
||||||
|
targetParentFolderArr.splice(targetParentFolderArr.length - 1, 1)
|
||||||
|
targetParentFolder = targetParentFolderArr.join('/')
|
||||||
|
} else {
|
||||||
|
targetFolderName = sourceFolderName
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if 'sourceFolder' is already an URI
|
||||||
|
const sourceFolderUri = await this.getFolderUri(sourceFolder, accessToken)
|
||||||
|
|
||||||
// checks if 'targetParentFolder' is already a URI
|
// checks if 'targetParentFolder' is already a URI
|
||||||
const targetParentFolderUri = isUri(targetParentFolder)
|
const targetParentFolderUri = await this.getFolderUri(
|
||||||
? targetParentFolder
|
targetParentFolder,
|
||||||
: await this.getFolderUri(targetParentFolder, accessToken)
|
accessToken
|
||||||
|
)
|
||||||
|
|
||||||
const sourceFolderId = sourceFolderUri?.split('/').pop()
|
const sourceFolderId = sourceFolderUri?.split('/').pop()
|
||||||
const url = sourceFolderUri
|
|
||||||
|
|
||||||
const { result: folder } = await this.requestClient
|
const { result: folder } = await this.requestClient
|
||||||
.patch<Folder>(
|
.patch<Folder>(
|
||||||
`${this.serverUrl}${url}`,
|
`${this.serverUrl}${sourceFolderUri}`,
|
||||||
{
|
{
|
||||||
id: sourceFolderId,
|
id: sourceFolderId,
|
||||||
name: targetFolderName,
|
name: targetFolderName,
|
||||||
|
|||||||
@@ -317,6 +317,25 @@ export default class SASjs {
|
|||||||
return await this.sasViyaApiClient?.deleteFolder(folderPath, accessToken)
|
return await this.sasViyaApiClient?.deleteFolder(folderPath, accessToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lists children folders for given Viya folder.
|
||||||
|
* @param sourceFolder - the full path (eg `/Public/example/myFolder`) or URI of the source folder listed. Providing URI instead of path will save one extra request.
|
||||||
|
* @param accessToken - an access token for authorizing the request.
|
||||||
|
*/
|
||||||
|
public async listFolder(
|
||||||
|
sourceFolder: string,
|
||||||
|
accessToken?: string,
|
||||||
|
limit?: number
|
||||||
|
) {
|
||||||
|
this.isMethodSupported('listFolder', ServerType.SasViya)
|
||||||
|
|
||||||
|
return await this.sasViyaApiClient?.listFolder(
|
||||||
|
sourceFolder,
|
||||||
|
accessToken,
|
||||||
|
limit
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Moves folder to a new location. The folder may be renamed at the same time.
|
* Moves folder to a new location. The folder may be renamed at the same time.
|
||||||
* @param sourceFolder - the full path (eg `/Public/example/myFolder`) or URI of the source folder to be moved. Providing URI instead of path will save one extra request.
|
* @param sourceFolder - the full path (eg `/Public/example/myFolder`) or URI of the source folder to be moved. Providing URI instead of path will save one extra request.
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import { RequestClient } from '../request/RequestClient'
|
||||||
|
import { SASViyaApiClient } from '../SASViyaApiClient'
|
||||||
|
import axios from 'axios'
|
||||||
|
jest.mock('axios')
|
||||||
|
const mockedAxios = axios as jest.Mocked<typeof axios>
|
||||||
|
|
||||||
|
describe('FolderOperations', () => {
|
||||||
|
const sasViyaApiClient = new SASViyaApiClient(
|
||||||
|
'https://sample.server.com',
|
||||||
|
'/Public',
|
||||||
|
'Context',
|
||||||
|
new RequestClient('https://sample.server.com')
|
||||||
|
)
|
||||||
|
|
||||||
|
beforeEach(() => {})
|
||||||
|
|
||||||
|
it('should move and rename folder', async (done) => {
|
||||||
|
mockFetchResponse(false)
|
||||||
|
|
||||||
|
let res: any = await sasViyaApiClient.moveFolder(
|
||||||
|
'/Test/fromFolder/oldName',
|
||||||
|
'/Test/toFolder/newName',
|
||||||
|
'newName',
|
||||||
|
'token'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.folder.name).toEqual('newName')
|
||||||
|
expect(res.folder.parentFolderUri.split('=')[1]).toEqual('/Test/toFolder')
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should move and keep the name of folder', async (done) => {
|
||||||
|
mockFetchResponse(true)
|
||||||
|
|
||||||
|
let res: any = await sasViyaApiClient.moveFolder(
|
||||||
|
'/Test/fromFolder/oldName',
|
||||||
|
'/Test/toFolder',
|
||||||
|
'toFolder',
|
||||||
|
'token'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.folder.name).toEqual('oldName')
|
||||||
|
expect(res.folder.parentFolderUri.split('=')[1]).toEqual('/Test/toFolder')
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should only rename folder', async (done) => {
|
||||||
|
mockFetchResponse(false)
|
||||||
|
|
||||||
|
let res: any = await sasViyaApiClient.moveFolder(
|
||||||
|
'/Test/toFolder/oldName',
|
||||||
|
'/Test/toFolder/newName',
|
||||||
|
'newName',
|
||||||
|
'token'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(res.folder.name).toEqual('newName')
|
||||||
|
expect(res.folder.parentFolderUri.split('=')[1]).toEqual('/Test/toFolder')
|
||||||
|
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
const mockFetchResponse = (targetFolderExists: boolean) => {
|
||||||
|
mockedAxios.patch.mockImplementation((url: any, request: any) => {
|
||||||
|
return Promise.resolve({ status: 200, data: { folder: request } })
|
||||||
|
})
|
||||||
|
|
||||||
|
mockedAxios.get.mockImplementation((url: any, request: any) => {
|
||||||
|
if (!targetFolderExists && url.includes('newName')) {
|
||||||
|
return Promise.resolve(undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve({
|
||||||
|
status: 200,
|
||||||
|
data: {
|
||||||
|
id: url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user