refactor(files): Migrate files service to functions from @nextcloud/files

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Ferdinand Thiessen 2024-06-10 22:38:14 +02:00
parent 9ea557e34a
commit 85e6cb4ccc
No known key found for this signature in database
GPG key ID: 45FAE7268762B400
2 changed files with 17 additions and 101 deletions

View file

@ -3,68 +3,25 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { ContentsWithRoot } from '@nextcloud/files'
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
import type { FileStat, ResponseDataDetailed } from 'webdav'
import { CancelablePromise } from 'cancelable-promise'
import { File, Folder, davParsePermissions, davGetDefaultPropfind } from '@nextcloud/files'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { File, Folder, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
import { client } from './WebdavClient.ts'
import logger from '../logger.js'
import { getClient, rootPath } from './WebdavClient'
import { hashCode } from '../utils/hashUtils'
import logger from '../logger'
/**
* Slim wrapper over `@nextcloud/files` `davResultToNode` to allow using the function with `Array.map`
* @param node The node returned by the webdav library
*/
export const resultToNode = (node: FileStat): File | Folder => davResultToNode(node)
const client = getClient()
interface ResponseProps extends DAVResultResponseProps {
permissions: string,
fileid: number,
size: number,
}
export const resultToNode = function(node: FileStat): File | Folder {
const userId = getCurrentUser()?.uid
if (!userId) {
throw new Error('No user id found')
}
const props = node.props as ResponseProps
const permissions = davParsePermissions(props?.permissions)
const owner = (props['owner-id'] || userId).toString()
const source = generateRemoteUrl('dav' + rootPath + node.filename)
const id = props?.fileid < 0
? hashCode(source)
: props?.fileid as number || 0
const nodeData = {
id,
source,
mtime: new Date(node.lastmod),
mime: node.mime || 'application/octet-stream',
size: props?.size as number || 0,
permissions,
owner,
root: rootPath,
attributes: {
...node,
...props,
hasPreview: props?.['has-preview'],
failed: props?.fileid < 0,
},
}
delete nodeData.attributes.props
return node.type === 'file'
? new File(nodeData)
: new Folder(nodeData)
}
export const getContents = (path = '/'): Promise<ContentsWithRoot> => {
export const getContents = (path = '/'): CancelablePromise<ContentsWithRoot> => {
const controller = new AbortController()
const propfindPayload = davGetDefaultPropfind()
path = `${davRootPath}${path}`
return new CancelablePromise(async (resolve, reject, onCancel) => {
onCancel(() => controller.abort())
try {
@ -77,13 +34,14 @@ export const getContents = (path = '/'): Promise<ContentsWithRoot> => {
const root = contentsResponse.data[0]
const contents = contentsResponse.data.slice(1)
if (root.filename !== path) {
if (root.filename !== path && `${root.filename}/` !== path) {
logger.debug(`Exepected "${path}" but got filename "${root.filename}" instead.`)
throw new Error('Root node does not match requested path')
}
resolve({
folder: resultToNode(root) as Folder,
contents: contents.map(result => {
contents: contents.map((result) => {
try {
return resultToNode(result)
} catch (error) {

View file

@ -2,48 +2,6 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { davGetClient } from '@nextcloud/files'
import { createClient, getPatcher } from 'webdav'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser, getRequestToken, onRequestTokenUpdate } from '@nextcloud/auth'
export const rootPath = `/files/${getCurrentUser()?.uid}`
export const defaultRootUrl = generateRemoteUrl('dav' + rootPath)
export const getClient = (rootUrl = defaultRootUrl) => {
const client = createClient(rootUrl)
// set CSRF token header
const setHeaders = (token: string | null) => {
client?.setHeaders({
// Add this so the server knows it is an request from the browser
'X-Requested-With': 'XMLHttpRequest',
// Inject user auth
requesttoken: token ?? '',
});
}
// refresh headers when request token changes
onRequestTokenUpdate(setHeaders)
setHeaders(getRequestToken())
/**
* Allow to override the METHOD to support dav REPORT
*
* @see https://github.com/perry-mitchell/webdav-client/blob/8d9694613c978ce7404e26a401c39a41f125f87f/source/request.ts
*/
const patcher = getPatcher()
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// https://github.com/perry-mitchell/hot-patcher/issues/6
patcher.patch('fetch', (url: string, options: RequestInit): Promise<Response> => {
const headers = options.headers as Record<string, string>
if (headers?.method) {
options.method = headers.method
delete headers.method
}
return fetch(url, options)
})
return client;
}
export const client = davGetClient()