Skip to content

Commit

Permalink
Merge pull request #11190 from owncloud/refactor/id-based-webdav-oper…
Browse files Browse the repository at this point in the history
…ations

feat: add file id support to webdav client
  • Loading branch information
JammingBen authored Jul 16, 2024
2 parents 0aaa43c + 2ad22dc commit 7746e12
Show file tree
Hide file tree
Showing 20 changed files with 158 additions and 136 deletions.
2 changes: 1 addition & 1 deletion packages/web-app-files/src/services/folder/loaderSpace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class FolderLoaderSpace implements FolderLoader {
signal2,
space: SpaceResource,
path: string = null,
fileId: string | number = null,
fileId: string = null,
options: FolderLoaderOptions = {}
) {
try {
Expand Down
30 changes: 22 additions & 8 deletions packages/web-client/src/webdav/copyFiles.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import { urlJoin } from '../utils'
import { SpaceResource } from '../helpers'
import { DAV, DAVRequestOptions } from './client'
import { WebDavOptions } from './types'
import { getWebDavPath } from './utils'

export const CopyFilesFactory = (dav: DAV, options: WebDavOptions) => {
return {
copyFiles(
sourceSpace: SpaceResource,
{ path: sourcePath }: { path: string },
{ path: sourcePath, fileId: sourceFileId }: { path?: string; fileId?: string },
targetSpace: SpaceResource,
{ path: targetPath }: { path: string },
{
path: targetPath,
parentFolderId,
name
}: { path?: string; parentFolderId?: string; name?: string },
{ overwrite, ...opts }: { overwrite?: boolean } & DAVRequestOptions = {}
) {
return dav.copy(
urlJoin(sourceSpace.webDavPath, sourcePath),
urlJoin(targetSpace.webDavPath, targetPath),
{ overwrite: overwrite || false, ...opts }
)
const sourceWebDavPath = getWebDavPath(sourceSpace, {
fileId: sourceFileId,
path: sourcePath
})

const targetWebDavPath = getWebDavPath(targetSpace, {
fileId: parentFolderId,
path: targetPath,
name
})

return dav.copy(sourceWebDavPath, targetWebDavPath, {
overwrite: overwrite || false,
...opts
})
}
}
}
19 changes: 12 additions & 7 deletions packages/web-client/src/webdav/createFolder.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { FolderResource, SpaceResource } from '../helpers'
import { GetFileInfoFactory } from './getFileInfo'
import { urlJoin } from '../utils'
import { DAV, DAVRequestOptions } from './client/dav'
import { WebDavOptions } from './types'
import { getWebDavPath } from './utils'

type CreateFolderOptions = {
path: string
parentFolderId?: string
folderName?: string
fetchFolder?: boolean
} & DAVRequestOptions

export const CreateFolderFactory = (
dav: DAV,
Expand All @@ -12,15 +19,13 @@ export const CreateFolderFactory = (
return {
async createFolder(
space: SpaceResource,
{
path,
fetchFolder = true,
...opts
}: { path?: string; fetchFolder?: boolean } & DAVRequestOptions
{ path, parentFolderId, folderName, fetchFolder = true, ...opts }: CreateFolderOptions
): Promise<FolderResource> {
await dav.mkcol(urlJoin(space.webDavPath, path, { leadingSlash: true }))
const webDavPath = getWebDavPath(space, { fileId: parentFolderId, path, name: folderName })
await dav.mkcol(webDavPath)

if (fetchFolder) {
// FIXME: mkcol doesn't return a fileId: https://github.com/owncloud/ocis/issues/9618
return getFileInfoFactory.getFileInfo(space, { path }, opts)
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/web-client/src/webdav/deleteFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DAV, DAVRequestOptions } from './client'
export const DeleteFileFactory = (dav: DAV, options: WebDavOptions) => {
return {
deleteFile(space: SpaceResource, { path, ...opts }: { path: string } & DAVRequestOptions) {
// FIXME: id-based not possible because of the server: https://github.com/owncloud/ocis/issues/9619
return dav.delete(urlJoin(space.webDavPath, path), opts)
}
}
Expand Down
7 changes: 4 additions & 3 deletions packages/web-client/src/webdav/getFileContents.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { urlJoin } from '../utils'
import { SpaceResource } from '../helpers'
import { WebDavOptions } from './types'
import { DAV, DAVRequestOptions } from './client'
import { HttpError } from '../errors'
import { ResponseType } from 'axios'
import { getWebDavPath } from './utils'

export type GetFileContentsResponse = {
body: any
Expand All @@ -14,7 +14,7 @@ export const GetFileContentsFactory = (dav: DAV, { axiosClient }: WebDavOptions)
return {
async getFileContents(
space: SpaceResource,
{ path }: { path?: string },
{ fileId, path }: { fileId?: string; path?: string },
{
responseType = 'text',
noCache = true,
Expand All @@ -26,7 +26,8 @@ export const GetFileContentsFactory = (dav: DAV, { axiosClient }: WebDavOptions)
} & DAVRequestOptions = {}
): Promise<GetFileContentsResponse> {
try {
const response = await axiosClient.get(dav.getFileUrl(urlJoin(space.webDavPath, path)), {
const webDavPath = getWebDavPath(space, { fileId, path })
const response = await axiosClient.get(dav.getFileUrl(webDavPath), {
responseType,
headers: {
...(noCache && { 'Cache-Control': 'no-cache' }),
Expand Down
2 changes: 1 addition & 1 deletion packages/web-client/src/webdav/getFileInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const GetFileInfoFactory = (
return {
async getFileInfo(
space: SpaceResource,
resource?: { path?: string; fileId?: string | number },
resource?: { path?: string; fileId?: string },
options?: ListFilesOptions
): Promise<Resource> {
return (
Expand Down
4 changes: 1 addition & 3 deletions packages/web-client/src/webdav/getFileUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@ export const GetFileUrlFactory = (
} & DAVRequestOptions
): Promise<string> {
const inlineDisposition = disposition === 'inline'
const { path } = resource
let { downloadURL } = resource

let signed = true
if (!downloadURL && !inlineDisposition) {
// compute unsigned url
const webDavPath = space ? urlJoin(space.webDavPath, path) : resource.webDavPath
downloadURL = version
? dav.getFileUrl(urlJoin('meta', resource.fileId, 'v', version))
: dav.getFileUrl(webDavPath)
: dav.getFileUrl(resource.webDavPath)

if (username && doHeadRequest) {
await axiosClient.head(downloadURL)
Expand Down
5 changes: 0 additions & 5 deletions packages/web-client/src/webdav/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { SearchFactory } from './search'
import { GetPathForFileIdFactory } from './getPathForFileId'
import { DAV } from './client/dav'
import { ListFileVersionsFactory } from './listFileVersions'
import { ListFilesByIdFactory } from './listFilesById'
import { SetFavoriteFactory } from './setFavorite'
import { ListFavoriteFilesFactory } from './listFavoriteFiles'

Expand All @@ -35,9 +34,6 @@ export const webdav = (options: WebDavOptions): WebDAV => {
const listFilesFactory = ListFilesFactory(dav, pathForFileIdFactory, options)
const { listFiles } = listFilesFactory

const listFilesByIdFactory = ListFilesByIdFactory(dav, options)
const { listFilesById } = listFilesByIdFactory

const getFileInfoFactory = GetFileInfoFactory(listFilesFactory, options)
const { getFileInfo } = getFileInfoFactory

Expand Down Expand Up @@ -77,7 +73,6 @@ export const webdav = (options: WebDavOptions): WebDAV => {
getPublicFileUrl,
getPathForFileId,
listFiles,
listFilesById,
listFileVersions,
moveFiles,
putFileContents,
Expand Down
11 changes: 7 additions & 4 deletions packages/web-client/src/webdav/listFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { urlJoin } from '../utils'
import { DAV, DAVRequestOptions } from './client'
import { GetPathForFileIdFactory } from './getPathForFileId'
import { WebDavOptions } from './types'
import { getWebDavPath } from './utils'

export type ListFilesOptions = {
depth?: number
Expand All @@ -30,7 +31,7 @@ export const ListFilesFactory = (
return {
async listFiles(
space: SpaceResource,
{ path, fileId }: { path?: string; fileId?: string | number } = {},
{ path, fileId }: { path?: string; fileId?: string } = {},
{ depth = 1, davProperties, isTrash = false, ...opts }: ListFilesOptions = {}
): Promise<ListFilesResult> {
let webDavResources: WebDavResponseResource[]
Expand Down Expand Up @@ -95,14 +96,16 @@ export const ListFilesFactory = (
}

const listFilesCorrectedPath = async () => {
const correctPath = await pathForFileIdFactory.getPathForFileId(fileId.toString())
const correctPath = await pathForFileIdFactory.getPathForFileId(fileId)
return this.listFiles(space, { path: correctPath }, { depth, davProperties })
}

try {
let webDavPath = urlJoin(space.webDavPath, path)
let webDavPath = ''
if (isTrash) {
webDavPath = buildWebDavSpacesTrashPath(space.id.toString())
webDavPath = buildWebDavSpacesTrashPath(space.id)
} else {
webDavPath = getWebDavPath(space, { fileId, path })
}

webDavResources = await dav.propfind(webDavPath, {
Expand Down
30 changes: 0 additions & 30 deletions packages/web-client/src/webdav/listFilesById.ts

This file was deleted.

29 changes: 22 additions & 7 deletions packages/web-client/src/webdav/moveFiles.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
import { SpaceResource } from '../helpers'
import { WebDavOptions } from './types'
import { DAV, DAVRequestOptions } from './client'
import { getWebDavPath } from './utils'

export const MoveFilesFactory = (dav: DAV, options: WebDavOptions) => {
return {
moveFiles(
sourceSpace: SpaceResource,
{ path: sourcePath }: { path: string },
{ path: sourcePath, fileId: sourceFileId }: { path?: string; fileId?: string },
targetSpace: SpaceResource,
{ path: targetPath }: { path: string },
{
path: targetPath,
parentFolderId,
name
}: { path?: string; parentFolderId?: string; name?: string },
{ overwrite, ...opts }: { overwrite?: boolean } & DAVRequestOptions = {}
) {
return dav.move(
`${sourceSpace.webDavPath}/${sourcePath || ''}`,
`${targetSpace.webDavPath}/${targetPath || ''}`,
{ overwrite: overwrite || false, ...opts }
)
const sourceWebDavPath = getWebDavPath(sourceSpace, {
fileId: sourceFileId,
path: sourcePath
})

const targetWebDavPath = getWebDavPath(targetSpace, {
fileId: parentFolderId,
path: targetPath,
name
})

return dav.move(sourceWebDavPath, targetWebDavPath, {
overwrite: overwrite || false,
...opts
})
}
}
}
30 changes: 20 additions & 10 deletions packages/web-client/src/webdav/putFileContents.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import { urlJoin } from '../utils'
import { SpaceResource } from '../helpers'
import { GetFileInfoFactory } from './getFileInfo'
import { WebDavOptions } from './types'
import { DAV, DAVRequestOptions } from './client'
import { ProgressEventCallback } from 'webdav'
import { getWebDavPath } from './utils'

type PutFileContentsOptions = {
fileName?: string
parentFolderId?: string
path?: string
content?: string | ArrayBuffer
previousEntityTag?: string
overwrite?: boolean
onUploadProgress?: ProgressEventCallback
} & DAVRequestOptions

export const PutFileContentsFactory = (
dav: DAV,
Expand All @@ -14,28 +24,28 @@ export const PutFileContentsFactory = (
async putFileContents(
space: SpaceResource,
{
fileName,
path,
parentFolderId,
content = '',
previousEntityTag = '',
overwrite,
onUploadProgress = null,
...opts
}: {
path?: string
content?: string | ArrayBuffer
previousEntityTag?: string
overwrite?: boolean
onUploadProgress?: ProgressEventCallback
} & DAVRequestOptions
}: PutFileContentsOptions
) {
await dav.put(urlJoin(space.webDavPath, path), content, {
const webDavPath = getWebDavPath(space, { fileId: parentFolderId, name: fileName, path })
const { result } = await dav.put(webDavPath, content, {
previousEntityTag,
overwrite,
onUploadProgress,
...opts
})

return getFileInfoFactory.getFileInfo(space, { path })
return getFileInfoFactory.getFileInfo(space, {
fileId: result.headers.get('Oc-Fileid'),
path
})
}
}
}
8 changes: 4 additions & 4 deletions packages/web-client/src/webdav/restoreFileVersion.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { SpaceResource } from '../helpers'
import { WebDavOptions } from './types'
import { urlJoin } from '../utils'
import { Resource } from '../helpers'
import { DAV, DAVRequestOptions } from './client'
import { getWebDavPath } from './utils'

export const RestoreFileVersionFactory = (dav: DAV, options: WebDavOptions) => {
return {
restoreFileVersion(
space: SpaceResource,
{ id, path }: Resource,
{ parentFolderId, name, path }: { parentFolderId?: string; name?: string; path?: string },
versionId: string,
opts: DAVRequestOptions = {}
) {
const webDavPath = urlJoin(space.webDavPath, path)
const source = urlJoin('meta', id, 'v', versionId, { leadingSlash: true })
const webDavPath = getWebDavPath(space, { path, fileId: parentFolderId, name })
const source = urlJoin('meta', parentFolderId, 'v', versionId, { leadingSlash: true })
const target = urlJoin('files', webDavPath, { leadingSlash: true })
return dav.copy(source, target, opts)
}
Expand Down
2 changes: 0 additions & 2 deletions packages/web-client/src/webdav/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { RestoreFileVersionFactory } from './restoreFileVersion'
import { ClearTrashBinFactory } from './clearTrashBin'
import { SearchFactory } from './search'
import { GetPathForFileIdFactory } from './getPathForFileId'
import { ListFilesByIdFactory } from './listFilesById'
import { SetFavoriteFactory } from './setFavorite'
import { ListFavoriteFilesFactory } from './listFavoriteFiles'
import { AxiosInstance } from 'axios'
Expand All @@ -30,7 +29,6 @@ export interface WebDAV {
getPublicFileUrl: ReturnType<typeof GetPublicFileUrlFactory>['getPublicFileUrl']
revokeUrl: ReturnType<typeof GetFileUrlFactory>['revokeUrl']
listFiles: ReturnType<typeof ListFilesFactory>['listFiles']
listFilesById: ReturnType<typeof ListFilesByIdFactory>['listFilesById']
createFolder: ReturnType<typeof CreateFolderFactory>['createFolder']
getFileContents: ReturnType<typeof GetFileContentsFactory>['getFileContents']
putFileContents: ReturnType<typeof PutFileContentsFactory>['putFileContents']
Expand Down
Loading

0 comments on commit 7746e12

Please sign in to comment.